BAN: implement exchange sort and test for it

This commit is contained in:
Bananymous 2023-12-07 10:16:15 +02:00
parent e935a33a4d
commit 43458cc74f
4 changed files with 74 additions and 0 deletions

20
BAN/include/BAN/Sort.h Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <BAN/Swap.h>
#include <BAN/Traits.h>
namespace BAN
{
template<typename It, typename Comp = less<typename It::value_type>>
void sort_exchange(It begin, It end, Comp comp = {})
{
for (It lhs = begin; lhs != end; ++lhs)
for (It rhs = lhs; ++rhs != end;)
if (!comp(*lhs, *rhs))
swap(*lhs, *rhs);
}
}

View File

@ -28,6 +28,7 @@ set(USERSPACE_PROJECTS
test
test-globals
test-framebuffer
test-sort
touch
u8sum
whoami

View File

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.26)
project(test-sort CXX)
set(SOURCES
main.cpp
)
add_executable(test-sort ${SOURCES})
target_compile_options(test-sort PUBLIC -O2 -g)
target_link_libraries(test-sort PUBLIC libc)
add_custom_target(test-sort-install
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/test-sort ${BANAN_BIN}/
DEPENDS test-sort
)

View File

@ -0,0 +1,37 @@
#include <BAN/Vector.h>
#include <BAN/Sort.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
template<typename T>
bool is_sorted(BAN::Vector<T>& vec)
{
for (size_t i = 0; i < vec.size() - 1; i++)
if (vec[i] > vec[i + 1])
return false;
return true;
}
#define CURRENT_NS() ({ timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); ts.tv_sec * 1'000'000'000 + ts.tv_nsec; })
#define TEST(name, function, count) do { \
BAN::Vector<int> ivec(count, 0); \
for (int& i : ivec) \
i = rand() % 100; \
uint64_t start_ns = CURRENT_NS(); \
function(ivec.begin(), ivec.end()); \
uint64_t end_ns = CURRENT_NS(); \
uint64_t dur_us = (end_ns - start_ns) / 1000; \
printf(name " (" #count "): %s\n", is_sorted(ivec) ? "success" : "fail"); \
printf(" took %" PRIu64 ".%03" PRIu64 " ms\n", dur_us / 1000, dur_us % 1000); \
} while (0)
int main()
{
srand(time(0));
TEST("exchange sort", BAN::sort_exchange, 100);
TEST("exchange sort", BAN::sort_exchange, 1000);
TEST("exchange sort", BAN::sort_exchange, 10000);
}