mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-19 16:54:08 +10:00
Began cleaning up this project for a soft reboot
This commit is contained in:
@@ -1,40 +0,0 @@
|
||||
#include "toy.h"
|
||||
|
||||
//util macros
|
||||
#define TOY_ARRAY_EXPAND(array) ((array) = ((array) != NULL && (array)->count + 1 > (array)->capacity ? Toy_resizeArray((array), (array)->capacity * TOY_ARRAY_EXPANSION_RATE) : (array)))
|
||||
#define TOY_ARRAY_PUSHBACK(array, value) (TOY_ARRAY_EXPAND(array), (array)->data[(array)->count++] = (value))
|
||||
|
||||
void stress_fillArray(Toy_Array** array) {
|
||||
//Toy_Value is either 8 or 16 bytes
|
||||
for (int i = 0; i < 10 * 1000 * 1000; i++) {
|
||||
TOY_ARRAY_PUSHBACK(*array, TOY_VALUE_FROM_INTEGER(i));
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
//Compare different memory strategies for Toy_Array
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
/*
|
||||
|
||||
//malloc
|
||||
Toy_Array* array = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY);
|
||||
stress_fillArray(&array);
|
||||
Toy_resizeArray(array, 0);
|
||||
|
||||
/*/
|
||||
|
||||
//Toy_Bucket
|
||||
benchBucket = Toy_allocateBucket(1024 * 1024 * 200); //200MB
|
||||
|
||||
Toy_Array* array = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY);
|
||||
stress_fillArray(&array);
|
||||
Toy_resizeArray(array, 0);
|
||||
|
||||
Toy_freeBucket(&benchBucket);
|
||||
|
||||
//*/
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
#compiler settings
|
||||
CC=gcc
|
||||
CFLAGS+=-std=c17 -g -Wall -Werror -Wextra -Wpedantic -Wformat=2 -Wno-newline-eof
|
||||
LIBS+=-lm
|
||||
LDFLAGS+=
|
||||
|
||||
ifeq ($(shell uname),Linux)
|
||||
LDFLAGS=-Wl,--gc-sections
|
||||
else ifeq ($(OS),Windows_NT)
|
||||
LDFLAGS=-Wl,--gc-sections
|
||||
else ifeq ($(shell uname),Darwin)
|
||||
LDFLAGS=-Wl,-dead_strip
|
||||
else
|
||||
@echo "LDFLAGS set failed - what platform is this?"
|
||||
endif
|
||||
|
||||
#patched incl
|
||||
TOY_SOURCEDIR=source
|
||||
|
||||
#directories
|
||||
TEST_ROOTDIR=../../..
|
||||
TEST_SOURCEDIR=$(TEST_ROOTDIR)/$(TOY_SOURCEDIR)
|
||||
TEST_CASESDIR=.
|
||||
|
||||
TEST_OUTDIR=out
|
||||
TEST_OBJDIR=obj
|
||||
|
||||
#file names
|
||||
TEST_SOURCEFILES=$(wildcard $(TEST_SOURCEDIR)/*.c)
|
||||
TEST_CASESFILES=$(wildcard $(TEST_CASESDIR)/bench_*.c)
|
||||
|
||||
#build the object files, compile the test cases, and run
|
||||
all: clean
|
||||
$(MAKE) build-source
|
||||
$(MAKE) build-cases
|
||||
$(MAKE) build-link
|
||||
$(MAKE) build-run
|
||||
|
||||
#targets for each step
|
||||
.PHONY: build-source
|
||||
build-source: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_SOURCEFILES:.c=.o)))
|
||||
|
||||
.PHONY: build-cases
|
||||
build-cases: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_CASESFILES:.c=.o)))
|
||||
|
||||
.PHONY: build-link
|
||||
build-link: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.exe)))
|
||||
|
||||
.PHONY: build-run
|
||||
build-run: $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.exe))) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.run)))
|
||||
|
||||
#compilation steps
|
||||
$(TEST_OBJDIR)/%.o: $(TEST_SOURCEDIR)/%.c
|
||||
$(CC) -c -o $@ $< $(addprefix -I,$(TEST_SOURCEDIR)) $(CFLAGS) -fdata-sections -ffunction-sections
|
||||
|
||||
$(TEST_OBJDIR)/%.o: $(TEST_CASESDIR)/%.c
|
||||
$(CC) -c -o $@ $< $(addprefix -I,$(TEST_SOURCEDIR) $(TEST_CASESDIR)) $(CFLAGS) -fdata-sections -ffunction-sections
|
||||
|
||||
$(TEST_OUTDIR)/%.exe: $(TEST_OBJDIR)/%.o
|
||||
@$(CC) -o $@ $< $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_SOURCEFILES:.c=.o))) $(CFLAGS) $(LIBS) $(LDFLAGS)
|
||||
strip $@
|
||||
|
||||
.PRECIOUS: $(TEST_OUTDIR)/%.run
|
||||
$(TEST_OUTDIR)/%.run: $(TEST_OUTDIR)/%.exe
|
||||
@/usr/bin/time --format "User System\n%U %E" $<
|
||||
|
||||
#util targets
|
||||
$(TEST_OUTDIR):
|
||||
mkdir $(TEST_OUTDIR)
|
||||
|
||||
$(TEST_OBJDIR):
|
||||
mkdir $(TEST_OBJDIR)
|
||||
|
||||
#util commands
|
||||
.PHONY: clean
|
||||
clean:
|
||||
ifeq ($(shell uname),Linux)
|
||||
find . -type f -name '*.o' -delete
|
||||
find . -type f -name '*.a' -delete
|
||||
find . -type f -name '*.exe' -delete
|
||||
find . -type f -name '*.dll' -delete
|
||||
find . -type f -name '*.lib' -delete
|
||||
find . -type f -name '*.so' -delete
|
||||
find . -type f -name '*.dylib' -delete
|
||||
find . -type d -name 'out' -delete
|
||||
find . -type d -name 'obj' -delete
|
||||
else ifeq ($(OS),Windows_NT)
|
||||
$(RM) *.o *.a *.exe *.dll *.lib *.so *.dylib
|
||||
$(RM) out
|
||||
$(RM) obj
|
||||
else ifeq ($(shell uname),Darwin)
|
||||
find . -type f -name '*.o' -delete
|
||||
find . -type f -name '*.a' -delete
|
||||
find . -type f -name '*.exe' -delete
|
||||
find . -type f -name '*.dll' -delete
|
||||
find . -type f -name '*.lib' -delete
|
||||
find . -type f -name '*.so' -delete
|
||||
find . -type f -name '*.dylib' -delete
|
||||
find . -type d -name 'out' -delete
|
||||
find . -type d -name 'obj' -delete
|
||||
else
|
||||
@echo "Deletion failed - what platform is this?"
|
||||
endif
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
|
||||
These tests compared two memory solutions for `Toy_Array`, under different conditions. 'Pushes' is the number of iterations used in the following stress function:
|
||||
|
||||
```c
|
||||
//defined in toy_value.h
|
||||
#define TOY_VALUE_FROM_INTEGER(value) ((Toy_Value){{ .integer = value }, TOY_VALUE_INTEGER})
|
||||
|
||||
//util macros
|
||||
#define TOY_ARRAY_EXPAND(array) ((array) = ((array) != NULL && (array)->count + 1 > (array)->capacity ? Toy_resizeArray((array), (array)->capacity * TOY_ARRAY_EXPANSION_RATE) : (array)))
|
||||
#define TOY_ARRAY_PUSHBACK(array, value) (TOY_ARRAY_EXPAND(array), (array)->data[(array)->count++] = (value))
|
||||
|
||||
void stress_fillArray(Toy_Array** array) {
|
||||
//Toy_Value is either 8 or 16 bytes
|
||||
for (int i = 0; i < 10 * 1000 * 1000; i++) {
|
||||
TOY_ARRAY_PUSHBACK(*array, TOY_VALUE_FROM_INTEGER(i));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
'Memory' is the capacity of the `Toy_Bucket` when used. In the first set of results, the stress function was called once, while the second set called it 100 times, clearing the memory entirely each time. 'malloc' and 'bucket' shows the measured time taken for each situation.
|
||||
|
||||
```
|
||||
1x run
|
||||
|
||||
pushes: 1000 * 1000
|
||||
memory: 1024 * 1024 * 20
|
||||
malloc: 0.01 0:00.01
|
||||
bucket: 0.00 0:00.02
|
||||
|
||||
pushes: 10 * 1000 * 1000
|
||||
memory: 1024 * 1024 * 200
|
||||
malloc: 0.08 0:00.14
|
||||
bucket: 0.13 0:00.29
|
||||
```
|
||||
|
||||
```
|
||||
100x looped runs
|
||||
|
||||
pushes: 1000 * 1000
|
||||
memory: 1024 * 1024 * 20
|
||||
malloc: 0.94 0:01.47
|
||||
bucket: 1.02 0:02.60
|
||||
|
||||
pushes: 10 * 1000 * 1000
|
||||
memory: 1024 * 1024 * 200
|
||||
malloc: 8.28 0:15.77
|
||||
bucket: 11.81 0:30.06
|
||||
```
|
||||
@@ -1,63 +0,0 @@
|
||||
#include "toy_array.h"
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include "toy_bucket.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
Toy_Bucket* benchBucket = NULL;
|
||||
|
||||
Toy_Array* Toy_resizeArray(Toy_Array* paramArray, unsigned int capacity) {
|
||||
//allow the array to be 'lost', and freed with the bucket
|
||||
if (capacity == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//initial allocation
|
||||
if (paramArray == NULL) {
|
||||
Toy_Array* array = Toy_partitionBucket(&benchBucket, capacity * sizeof(Toy_Value) + sizeof(Toy_Array));
|
||||
|
||||
array->capacity = capacity;
|
||||
array->count = 0;
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
//if your array is growing, partition more space, then copy over the data
|
||||
if (paramArray->capacity < capacity) {
|
||||
Toy_Array* array = Toy_partitionBucket(&benchBucket, capacity * sizeof(Toy_Value) + sizeof(Toy_Array));
|
||||
|
||||
memcpy(array, paramArray, paramArray->count * sizeof(Toy_Value) + sizeof(Toy_Array)); //doesn't copy any blank space
|
||||
|
||||
array->capacity = capacity;
|
||||
array->count = paramArray->count;
|
||||
return array;
|
||||
}
|
||||
|
||||
//if some values will be removed, free them first, then return the result
|
||||
if (paramArray->count > capacity) {
|
||||
for (unsigned int i = capacity; i < paramArray->count; i++) {
|
||||
Toy_freeValue(paramArray->data[i]);
|
||||
}
|
||||
|
||||
paramArray->capacity = capacity; //don't worry about another allocation, this is faster
|
||||
paramArray->count = capacity;
|
||||
|
||||
return paramArray;
|
||||
}
|
||||
|
||||
//unreachable
|
||||
return paramArray;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Note: This needs to be pasted in the header:
|
||||
|
||||
```
|
||||
struct Toy_Bucket;
|
||||
|
||||
extern struct Toy_Bucket* benchBucket;
|
||||
```
|
||||
|
||||
*/
|
||||
@@ -1,34 +0,0 @@
|
||||
#include "toy_array.h"
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
Toy_Array* Toy_resizeArray(Toy_Array* paramArray, unsigned int capacity) {
|
||||
if (capacity == 0) {
|
||||
free(paramArray);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//if some values will be removed, free them first
|
||||
if (paramArray != NULL && paramArray->count > capacity) {
|
||||
for (unsigned int i = capacity; i < paramArray->count; i++) {
|
||||
Toy_freeValue(paramArray->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int originalCapacity = paramArray == NULL ? 0 : paramArray->capacity;
|
||||
|
||||
Toy_Array* array = realloc(paramArray, capacity * sizeof(Toy_Value) + sizeof(Toy_Array));
|
||||
|
||||
if (array == NULL) {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to resize a 'Toy_Array' from %d to %d capacity\n" TOY_CC_RESET, (int)originalCapacity, (int)capacity);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
array->capacity = capacity;
|
||||
array->count = paramArray == NULL ? 0 :
|
||||
(array->count > capacity ? capacity : array->count); //truncate lost data
|
||||
|
||||
return array;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#include "toy.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//generate an immense series of Toy_String instances to fill the buckets, thrn compare the time taken for each possible vale of TOY_BUCKET_IDEAL
|
||||
|
||||
static unsigned int hash(unsigned int x) {
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
x = ((x >> 16) ^ x);
|
||||
return x;
|
||||
}
|
||||
|
||||
static unsigned int seed = 42;
|
||||
|
||||
static unsigned int rng() {
|
||||
return seed = hash(seed);
|
||||
}
|
||||
|
||||
#define MAX 9
|
||||
const char* samples[] = { //9 entries
|
||||
"the",
|
||||
"quick",
|
||||
"brown",
|
||||
"fox",
|
||||
"jumped",
|
||||
"over",
|
||||
"the",
|
||||
"lazy",
|
||||
"dog",
|
||||
};
|
||||
|
||||
void stress_fillBucket(Toy_Bucket** bucketHandle) {
|
||||
for (unsigned int i = 0; i < 10000000; i++) {
|
||||
//create some leaf and node strings
|
||||
Toy_String* a = Toy_createString(bucketHandle, samples[rng() % MAX]);
|
||||
Toy_String* b = Toy_createString(bucketHandle, samples[rng() % MAX]);
|
||||
Toy_String* c = Toy_createString(bucketHandle, samples[rng() % MAX]);
|
||||
Toy_String* d = Toy_createString(bucketHandle, samples[rng() % MAX]);
|
||||
|
||||
Toy_String* l = Toy_concatStrings(bucketHandle, a, b);
|
||||
Toy_String* r = Toy_concatStrings(bucketHandle, c, d);
|
||||
Toy_concatStrings(bucketHandle, l, r);
|
||||
|
||||
// char* buffer = Toy_getStringRawBuffer(s);
|
||||
// printf("%s\n", buffer);
|
||||
// free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long long int measureDepth(Toy_Bucket* bucket) {
|
||||
return bucket == NULL ? 0 : 1 + measureDepth(bucket->next);
|
||||
}
|
||||
|
||||
static unsigned long long int measureCapacity(Toy_Bucket* bucket) {
|
||||
return bucket == NULL ? 0 : bucket->capacity + measureCapacity(bucket->next);
|
||||
}
|
||||
|
||||
static unsigned long long int measureCount(Toy_Bucket* bucket) {
|
||||
return bucket == NULL ? 0 : bucket->count + measureCount(bucket->next);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
|
||||
stress_fillBucket(&bucket);
|
||||
|
||||
unsigned long long int depth = measureDepth(bucket);
|
||||
unsigned long long int capacity = measureCapacity(bucket);
|
||||
unsigned long long int count = measureCount(bucket);
|
||||
|
||||
printf(TOY_CC_FONT_RED TOY_CC_BACK_YELLOW "Result: %u: %llu, %llu, %llu" TOY_CC_RESET "\n", TOY_BUCKET_IDEAL, depth, capacity, count);
|
||||
|
||||
Toy_freeBucket(&bucket);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
#compiler settings
|
||||
CC=gcc
|
||||
CFLAGS+=-std=c17 -g -Wall -Werror -Wextra -Wpedantic -Wformat=2 -Wno-newline-eof
|
||||
LIBS+=-lm
|
||||
LDFLAGS+=
|
||||
|
||||
ifeq ($(shell uname),Linux)
|
||||
LDFLAGS=-Wl,--gc-sections
|
||||
else ifeq ($(OS),Windows_NT)
|
||||
LDFLAGS=-Wl,--gc-sections
|
||||
else ifeq ($(shell uname),Darwin)
|
||||
LDFLAGS=-Wl,-dead_strip
|
||||
else
|
||||
@echo "LDFLAGS set failed - what platform is this?"
|
||||
endif
|
||||
|
||||
#patched incl
|
||||
TOY_SOURCEDIR=source
|
||||
|
||||
#directories
|
||||
TEST_ROOTDIR=../../..
|
||||
TEST_SOURCEDIR=$(TEST_ROOTDIR)/$(TOY_SOURCEDIR)
|
||||
TEST_CASESDIR=.
|
||||
|
||||
TEST_OUTDIR=out
|
||||
TEST_OBJDIR=obj
|
||||
|
||||
#file names
|
||||
TEST_SOURCEFILES=$(wildcard $(TEST_SOURCEDIR)/*.c)
|
||||
TEST_CASESFILES=$(wildcard $(TEST_CASESDIR)/bench_*.c)
|
||||
|
||||
#build the object files, compile the test cases, and run
|
||||
all: clean
|
||||
$(MAKE) TOY_BUCKET_IDEAL=16372 all-override
|
||||
$(MAKE) TOY_BUCKET_IDEAL=32756 all-override
|
||||
$(MAKE) TOY_BUCKET_IDEAL=65524 all-override
|
||||
$(MAKE) TOY_BUCKET_IDEAL=131060 all-override
|
||||
$(MAKE) TOY_BUCKET_IDEAL=262132 all-override
|
||||
|
||||
all-override: clean
|
||||
$(MAKE) build-source
|
||||
$(MAKE) build-cases
|
||||
$(MAKE) build-link
|
||||
$(MAKE) build-run
|
||||
|
||||
#targets for each step
|
||||
.PHONY: build-source
|
||||
build-source: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_SOURCEFILES:.c=.o)))
|
||||
|
||||
.PHONY: build-cases
|
||||
build-cases: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_CASESFILES:.c=.o)))
|
||||
|
||||
.PHONY: build-link
|
||||
build-link: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.exe)))
|
||||
|
||||
.PHONY: build-run
|
||||
build-run: $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.exe))) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.run)))
|
||||
|
||||
#compilation steps
|
||||
$(TEST_OBJDIR)/%.o: $(TEST_SOURCEDIR)/%.c
|
||||
$(CC) -DTOY_BUCKET_IDEAL=$(TOY_BUCKET_IDEAL) -c -o $@ $< $(addprefix -I,$(TEST_SOURCEDIR)) $(CFLAGS) -fdata-sections -ffunction-sections
|
||||
|
||||
$(TEST_OBJDIR)/%.o: $(TEST_CASESDIR)/%.c
|
||||
$(CC) -DTOY_BUCKET_IDEAL=$(TOY_BUCKET_IDEAL) -c -o $@ $< $(addprefix -I,$(TEST_SOURCEDIR) $(TEST_CASESDIR)) $(CFLAGS) -fdata-sections -ffunction-sections
|
||||
|
||||
$(TEST_OUTDIR)/%.exe: $(TEST_OBJDIR)/%.o
|
||||
@$(CC) -DTOY_BUCKET_IDEAL=$(TOY_BUCKET_IDEAL) -o $@ $< $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_SOURCEFILES:.c=.o))) $(CFLAGS) $(LIBS) $(LDFLAGS)
|
||||
strip $@
|
||||
|
||||
.PRECIOUS: $(TEST_OUTDIR)/%.run
|
||||
$(TEST_OUTDIR)/%.run: $(TEST_OUTDIR)/%.exe
|
||||
@/usr/bin/time --format "User System\n%U %E" $<
|
||||
|
||||
#util targets
|
||||
$(TEST_OUTDIR):
|
||||
mkdir $(TEST_OUTDIR)
|
||||
|
||||
$(TEST_OBJDIR):
|
||||
mkdir $(TEST_OBJDIR)
|
||||
|
||||
#util commands
|
||||
.PHONY: clean
|
||||
clean:
|
||||
ifeq ($(shell uname),Linux)
|
||||
find . -type f -name '*.o' -delete
|
||||
find . -type f -name '*.a' -delete
|
||||
find . -type f -name '*.exe' -delete
|
||||
find . -type f -name '*.dll' -delete
|
||||
find . -type f -name '*.lib' -delete
|
||||
find . -type f -name '*.so' -delete
|
||||
find . -type f -name '*.dylib' -delete
|
||||
find . -type d -name 'out' -delete
|
||||
find . -type d -name 'obj' -delete
|
||||
else ifeq ($(OS),Windows_NT)
|
||||
$(RM) *.o *.a *.exe *.dll *.lib *.so *.dylib
|
||||
$(RM) out
|
||||
$(RM) obj
|
||||
else ifeq ($(shell uname),Darwin)
|
||||
find . -type f -name '*.o' -delete
|
||||
find . -type f -name '*.a' -delete
|
||||
find . -type f -name '*.exe' -delete
|
||||
find . -type f -name '*.dll' -delete
|
||||
find . -type f -name '*.lib' -delete
|
||||
find . -type f -name '*.so' -delete
|
||||
find . -type f -name '*.dylib' -delete
|
||||
find . -type d -name 'out' -delete
|
||||
find . -type d -name 'obj' -delete
|
||||
else
|
||||
@echo "Deletion failed - what platform is this?"
|
||||
endif
|
||||
|
||||
Reference in New Issue
Block a user