Compare commits
3 Commits
ead8a6e04e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
78909ea0fe
|
|||
|
912faca620
|
|||
|
b1cca113ce
|
2
Makefile
2
Makefile
@@ -56,7 +56,7 @@ $(OBJ_DIR):
|
||||
mkdir -p $(OBJ_DIR)
|
||||
|
||||
# Benchmark rules
|
||||
$(BENCH_TARGET): $(BENCH_OBJ_DIR)/bench.o $(BENCH_OBJ_DIR)/vector.o $(BENCH_OBJ_DIR)/map.o
|
||||
$(BENCH_TARGET): $(BENCH_OBJ_DIR)/bench.o $(BENCH_OBJ_DIR)/vector.o $(BENCH_OBJ_DIR)/map.o $(BENCH_OBJ_DIR)/string.o
|
||||
$(CC) $(BENCH_FLAGS) -o $@ $^
|
||||
|
||||
$(BENCH_OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(BENCH_OBJ_DIR)
|
||||
|
||||
13
README.md
13
README.md
@@ -2,8 +2,9 @@
|
||||
<h1>Datum</h1>
|
||||
<h6><i>Collection of dynamic and generic data structures.</i></h6>
|
||||
|
||||
[](https://github.com/ceticamarco/datum/actions/workflows/gcc-build.yml)
|
||||
[](https://github.com/ceticamarco/datum/actions/workflows/clang-build.yml)
|
||||

|
||||

|
||||
|
||||
</div>
|
||||
|
||||
Datum is a collection of dynamic and generic data structures implemented from scratch in C with no external dependencies beyond
|
||||
@@ -232,12 +233,14 @@ $ ./test_bigint
|
||||
```
|
||||
|
||||
## Benchmark
|
||||
Under the [`benchmark/`](/benchmark/) folder, you can find a simple benchmark program that stress the `Vector` and the `Map` data structures. You can run it by issuing the following command:
|
||||
Under the [`benchmark/`](/benchmark/) folder, you can find a simple benchmark program that stress the `Vector`, `Map` and the `String` data structures.
|
||||
You can run it by issuing the following command:
|
||||
|
||||
```sh
|
||||
$ ./benchmark_datum
|
||||
Computing Vector average time...average time: 18 ms
|
||||
Computing Map average time...average time: 31 ms
|
||||
Computing Vector average time...average time: 19 ms
|
||||
Computing Map average time...average time: 55 ms
|
||||
Computing String average time...average time: 24 ms
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
@@ -6,6 +8,7 @@
|
||||
|
||||
#include "../src/vector.h"
|
||||
#include "../src/map.h"
|
||||
#include "../src/string.h"
|
||||
|
||||
typedef void (*test_fn_t)(size_t iterations);
|
||||
|
||||
@@ -13,20 +16,15 @@ void test_vector(size_t iterations) {
|
||||
vector_t *vec = vector_new(16, sizeof(int)).value.vector;
|
||||
|
||||
for (size_t idx = 0; idx < iterations; idx++) {
|
||||
vector_push(vec, &idx);
|
||||
vector_push(vec, &(int){idx});
|
||||
}
|
||||
|
||||
volatile uint64_t sum = 0; // prevent the compiler from optimizing away the sum
|
||||
volatile uint64_t sum = 0;
|
||||
for (size_t idx = 0; idx < iterations; idx++) {
|
||||
const int *val = (int*)vector_get(vec, idx).value.element;
|
||||
sum += *val;
|
||||
}
|
||||
|
||||
// Another trick to prevent compiler optimization
|
||||
if (sum == 0xB00B5) {
|
||||
printf("sum = %llu\n", (unsigned long long)sum);
|
||||
}
|
||||
|
||||
vector_destroy(vec);
|
||||
}
|
||||
|
||||
@@ -43,7 +41,7 @@ void test_map(size_t iterations) {
|
||||
map_add(map, key, (void*)value);
|
||||
}
|
||||
|
||||
volatile uint64_t sum = 0; // prevent the compiler from optimizing away the sum
|
||||
volatile uint64_t sum = 0;
|
||||
for (size_t idx = 0; idx < iterations; idx++) {
|
||||
snprintf(key, sizeof(key), "key_%zu", idx);
|
||||
|
||||
@@ -53,32 +51,68 @@ void test_map(size_t iterations) {
|
||||
|
||||
// Cleanup values
|
||||
for (size_t idx = 0; idx < map->capacity; idx++) {
|
||||
if (map->elements[idx].state == ENTRY_OCCUPIED) {
|
||||
int *val = (int*)map->elements[idx].value;
|
||||
free(val);
|
||||
}
|
||||
snprintf(key, sizeof(key), "key_%zu", idx);
|
||||
|
||||
int *val = (int*)map_get(map, key).value.element;
|
||||
free(val);
|
||||
|
||||
map_remove(map, key);
|
||||
}
|
||||
|
||||
map_destroy(map);
|
||||
}
|
||||
|
||||
void test_string(size_t iterations) {
|
||||
volatile size_t total_len = 0;
|
||||
|
||||
for (size_t idx = 0; idx < iterations; idx++) {
|
||||
string_t *str1 = string_new("hello").value.string;
|
||||
string_t *str2 = string_new(" World").value.string;
|
||||
|
||||
string_result_t concat = string_concat(str1, str2);
|
||||
string_result_t upper = string_to_upper(concat.value.string);
|
||||
total_len += string_size(upper.value.string);
|
||||
string_result_t needle = string_new("WORLD");
|
||||
string_result_t contains = string_contains(upper.value.string, needle.value.string);
|
||||
|
||||
if (contains.value.idx >= 0) {
|
||||
total_len += contains.value.idx;
|
||||
}
|
||||
|
||||
string_destroy(str1);
|
||||
string_destroy(str2);
|
||||
string_destroy(concat.value.string);
|
||||
string_destroy(upper.value.string);
|
||||
string_destroy(needle.value.string);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t now_ns(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
return (uint64_t)ts.tv_sec * 1000000000ULL + ts.tv_nsec;
|
||||
}
|
||||
|
||||
long long benchmark(test_fn_t fun, size_t iterations, size_t runs) {
|
||||
long long total = 0;
|
||||
|
||||
for (size_t idx = 0; idx < runs; idx++) {
|
||||
clock_t start = clock();
|
||||
uint64_t start = now_ns();
|
||||
fun(iterations);
|
||||
clock_t end = clock();
|
||||
uint64_t end = now_ns();
|
||||
|
||||
total += (long long)((end - start) * 1000 / CLOCKS_PER_SEC);
|
||||
total += (end - start);
|
||||
}
|
||||
|
||||
return total / runs;
|
||||
return (long long)(total / runs / 1000000);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// Do a warmup run
|
||||
test_vector(1000);
|
||||
test_map(1000);
|
||||
test_string(1000);
|
||||
|
||||
printf("Computing Vector average time...");
|
||||
fflush(stdout);
|
||||
@@ -88,5 +122,9 @@ int main(void) {
|
||||
fflush(stdout);
|
||||
printf("average time: %lld ms\n", benchmark(test_map, 1e5, 30));
|
||||
|
||||
printf("Computing String average time...");
|
||||
fflush(stdout);
|
||||
printf("average time: %lld ms\n", benchmark(test_string, 1e5, 30));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user