Skip to content

Commit

Permalink
Merge branch 'refactoring'
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikwidlund committed Jan 15, 2017
2 parents e84b695 + 1076c47 commit 4baf082
Show file tree
Hide file tree
Showing 53 changed files with 1,867 additions and 1,682 deletions.
59 changes: 28 additions & 31 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
AM_CFLAGS = -std=gnu11 -O3 -flto -fuse-linker-plugin
AM_CFLAGS = -std=gnu11 -g -O3 -flto -fuse-linker-plugin
AM_LDFLAGS = -static

SUBDIRS = docs
DIST_SUBDIRS = docs benchmark

EXTRA_DIST = \
CHANGES \
LICENSE \
README.rst

SOURCE_FILES = \
src/dynamic/vector.c \
src/dynamic/string.c \
src/dynamic/buffer.c \
src/dynamic/mapi.c \
src/dynamic/maps.c \
src/dynamic/cfarmhash.c
src/dynamic/map.c \
src/dynamic/hash.c

HEADER_FILES = \
src/dynamic/vector.h \
src/dynamic/string.h \
src/dynamic/buffer.h \
src/dynamic/mapi.h \
src/dynamic/maps.h \
src/dynamic/cfarmhash.h
src/dynamic/map.h \
src/dynamic/hash.h

AUTOMAKE_OPTIONS = subdir-objects
lib_LTLIBRARIES= libdynamic.la
Expand All @@ -33,14 +36,14 @@ mainheader_HEADERS = src/dynamic.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libdynamic.pc

MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in docs/Makefile.in libdynamic-?.?.?.tar.gz
MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in docs/Makefile.in benchmark/Makefile.in libdynamic-?.?.?.tar.gz
maintainer-clean-local:; rm -rf autotools m4 libdynamic-?.?.?

### unit tests ###

CHECK_CFLAGS = -std=gnu11 -O0 -g -ftest-coverage -fprofile-arcs
CHECK_LDADD = -L. -ldynamic_test -lcmocka
CHECK_LDFLAGS_EXTRA = -Wl,--wrap=malloc -Wl,--wrap=calloc -Wl,--wrap=realloc -Wl,--wrap=aligned_alloc
CHECK_LDFLAGS_EXTRA = -Wl,--wrap=malloc -Wl,--wrap=calloc -Wl,--wrap=realloc -Wl,--wrap=aligned_alloc -Wl,--wrap=abort

check_LIBRARIES = libdynamic_test.a
libdynamic_test_a_CFLAGS = $(CHECK_CFLAGS)
Expand All @@ -50,37 +53,31 @@ check_PROGRAMS = test/buffer
test_buffer_CFLAGS = $(CHECK_CFLAGS)
test_buffer_LDADD = $(CHECK_LDADD)
test_buffer_LDFLAGS = $(CHECK_LDFLAGS_EXTRA)
test_buffer_SOURCES = test/buffer.c test/memory.c
test_buffer_SOURCES = test/buffer.c test/mock.c

check_PROGRAMS += test/vector
test_vector_CFLAGS = $(CHECK_CFLAGS)
test_vector_LDADD = $(CHECK_LDADD)
test_vector_LDFLAGS = $(CHECK_LDFLAGS_EXTRA)
test_vector_SOURCES = test/vector.c test/memory.c
test_vector_SOURCES = test/vector.c test/mock.c

check_PROGRAMS += test/string
test_string_CFLAGS = $(CHECK_CFLAGS)
test_string_LDADD = $(CHECK_LDADD)
test_string_LDFLAGS = $(CHECK_LDFLAGS_EXTRA)
test_string_SOURCES = test/string.c test/memory.c

check_PROGRAMS += test/mapi
test_mapi_CFLAGS = $(CHECK_CFLAGS)
test_mapi_LDADD = $(CHECK_LDADD)
test_mapi_LDFLAGS = $(CHECK_LDFLAGS_EXTRA)
test_mapi_SOURCES = test/mapi.c test/memory.c

check_PROGRAMS += test/maps
test_maps_CFLAGS = $(CHECK_CFLAGS)
test_maps_LDADD = $(CHECK_LDADD)
test_maps_LDFLAGS = $(CHECK_LDFLAGS_EXTRA)
test_maps_SOURCES = test/maps.c test/memory.c

check_PROGRAMS += test/cfarmhash
test_cfarmhash_CFLAGS = $(CHECK_CFLAGS)
test_cfarmhash_LDADD = $(CHECK_LDADD)
test_cfarmhash_LDFLAGS = $(CHECK_LDFLAGS_EXTRA)
test_cfarmhash_SOURCES = test/cfarmhash.c test/memory.c
test_string_SOURCES = test/string.c test/mock.c

check_PROGRAMS += test/hash
test_hash_CFLAGS = $(CHECK_CFLAGS)
test_hash_LDADD = $(CHECK_LDADD)
test_hash_LDFLAGS = $(CHECK_LDFLAGS_EXTRA)
test_hash_SOURCES = test/hash.c test/mock.c

check_PROGRAMS += test/map
test_map_CFLAGS = $(CHECK_CFLAGS)
test_map_LDADD = $(CHECK_LDADD)
test_map_LDFLAGS = $(CHECK_LDFLAGS_EXTRA)
test_map_SOURCES = test/map.c test/mock.c

dist_noinst_SCRIPTS = test/valgrind.sh test/coverage.sh

Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Compiling and installing
========================

The source uses GNU Autotools (autoconf_, automake_, libtool_), so
compiling and installing is extremely simple:
compiling and installing is simple:

.. code-block:: shell
Expand Down
33 changes: 33 additions & 0 deletions benchmark/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
bin_PROGRAMS = vector map

vector_SOURCES = \
vector.c vector_dynamic.c vector_stdlib.cpp \
vector.h vector_dynamic.h vector_stdlib.h \
vector.R
vector_CFLAGS = -std=gnu11 -I../src -g -O3 -flto -fuse-linker-plugin
vector_CXXFLAGS = -I../src -g -O3 -flto -fuse-linker-plugin
vector_LDADD = ../libdynamic.la

map_SOURCES = \
map.c map_custom.c map_subclass.c map_dynamic.c map_unordered.cpp \
map.h map_custom.h map_subclass.h map_dynamic.h map_unordered.h \
map.R
map_CFLAGS = -std=gnu11 -I../src -g -O3 -flto -fuse-linker-plugin
map_CXXFLAGS = -I../src -g -O3 -flto -fuse-linker-plugin
map_LDADD = ../libdynamic.la

benchmark: vector.pdf map.pdf

vector.pdf: vector.dat vector.R
./vector.R

vector.dat: vector
./$^ > $@

map.pdf: map.dat map.R
./map.R

map.dat: map
./$^ > $@

CLEANFILES = *.dat *.pdf
4 changes: 4 additions & 0 deletions benchmark/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To build the benchmark, invoke
make benchmark

Which will produce map.pfd and vector.pfd. The benchmark require R, and the ggplot2, scales and sitools libraries.
48 changes: 48 additions & 0 deletions benchmark/map.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env Rscript

library(ggplot2)
library(scales)
library(sitools)
library(gridExtra)

data.map <- read.csv("map.dat", head=TRUE, sep=",")

g1 <- ggplot(legend = TRUE) +
labs(list(title = "Insert", x = "Map size", y = "Time/Operation (ns)")) +
theme(plot.title = element_text(size = 10),
axis.title.x = element_text(size = 8), axis.title.y = element_text(size = 8),
axis.text.x = element_text(size = 8), axis.text.y = element_text(size = 8)) +
geom_smooth(method = "loess", span = 0.5, data = data.map, aes(x = size, y = insert, colour = name)) +
scale_y_continuous(labels = comma) +
expand_limits(y = 0) +
scale_x_continuous(trans = log_trans(), breaks = 10^(0:10), labels = comma)
g1$labels$colour <- "Implementation"

g2 <- ggplot(legend = TRUE) +
labs(list(title = "Lookup", x = "Map size", y = "Time/Operation (ns)")) +
theme(plot.title = element_text(size = 10),
axis.title.x = element_text(size = 8), axis.title.y = element_text(size = 8),
axis.text.x = element_text(size = 8), axis.text.y = element_text(size = 8)) +
geom_smooth(method = "loess", span = 0.5, data = data.map, aes(x = size, y = at, colour = name)) +
scale_y_continuous(labels = comma) +
expand_limits(y = 0) +
scale_x_continuous(trans = log_trans(), breaks = 10^(0:10), labels = comma)
g2$labels$colour <- "Implementation"

g3 <- ggplot(legend = TRUE) +
labs(list(title = "Delete", x = "Map size", y = "Time/Operation (ns)")) +
theme(plot.title = element_text(size = 10),
axis.title.x = element_text(size = 8), axis.title.y = element_text(size = 8),
axis.text.x = element_text(size = 8), axis.text.y = element_text(size = 8)) +
geom_smooth(method = "loess", span = 0.5, data = data.map, aes(x = size, y = erase, colour = name)) +
scale_y_continuous(labels = comma) +
expand_limits(y = 0) +
scale_x_continuous(trans = log_trans(), breaks = 10^(0:10), labels = comma)
g3$labels$colour <- "Implementation"

pdf("map.pdf", width = 10, height = 10)
grid.arrange(g1, g2, g3, ncol=1, top = "libdynamic map benchmark")
#dev.off()

# g4 <- grid.arrangeGrob(g1, g2, g3, ncol=1, top = "libdynamic map benchmark")
#ggsave(g4, file = "map.pdf", width = 10, height = 10)
52 changes: 52 additions & 0 deletions benchmark/map.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "dynamic.h"

#include "map.h"
#include "map_custom.h"
#include "map_subclass.h"
#include "map_unordered.h"
#include "map_dynamic.h"

static map_metric metrics[] = {
{.name = "custom open addressing", .measure = map_custom},
{.name = "libdynamic", .measure = map_dynamic},
{.name = "std::map_unordered", .measure = map_unordered},
{.name = "libdynamic (subclass)", .measure = map_subclass}
};

uint64_t ntime(void)
{
struct timespec ts;

(void) clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
return ((uint64_t) ts.tv_sec * 1000000000) + ((uint64_t) ts.tv_nsec);
}

int main()
{
size_t i, n, n_min = 10, n_max = 1000000;
double k = 1.1;
uint32_t *a;
map_metric *m;

(void) fprintf(stdout, "name,size,insert,at,erase\n");
for (n = n_min; n < n_max; n = ceil(k * n))
{
a = calloc(n, sizeof *a);
for (i = 0; i < n; i ++)
a[i] = rand();

for (m = metrics; m < &metrics[sizeof metrics / sizeof metrics[0]]; m ++)
{
m->measure(m, a, n);
(void) fprintf(stdout, "%s,%lu,%f,%f,%f\n", m->name, n, m->insert, m->at, m->erase);
}

free(a);
}
}
16 changes: 16 additions & 0 deletions benchmark/map.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef BENCHMARKS_MAP_H_INCLUDED
#define BENCHMARKS_MAP_H_INCLUDED

typedef struct map_metric map_metric;
struct map_metric
{
char *name;
void (*measure)(map_metric *, uint32_t *, size_t);
double insert;
double at;
double erase;
};

uint64_t ntime(void);

#endif /* BENCHMARKS_MAP_H_INCLUDED */

0 comments on commit 4baf082

Please sign in to comment.