diff --git a/scripts/test_copy_speed.toy b/scripts/test_copy_speed.toy new file mode 100644 index 0000000..03b04d7 --- /dev/null +++ b/scripts/test_copy_speed.toy @@ -0,0 +1,16 @@ + + +fn identity(x) { + return x; +} + + +var dict: [int:int] = [:]; + +for (var i: int = 0; i < 1000; i++) { + dict[i] = i; +} + +for (var i: int = 0; i < 100_000; i++) { + var x = identity(dict); +} diff --git a/source/toy_literal.c b/source/toy_literal.c index 3598338..dac2ea3 100644 --- a/source/toy_literal.c +++ b/source/toy_literal.c @@ -119,6 +119,10 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) { Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); Toy_initLiteralArray(array); + //preallocate enough space + array->capacity = TOY_AS_ARRAY(original)->capacity; + array->literals = TOY_GROW_ARRAY(Toy_Literal, array->literals, 0, array->capacity); + //copy each element for (int i = 0; i < TOY_AS_ARRAY(original)->count; i++) { Toy_pushLiteralArray(array, TOY_AS_ARRAY(original)->literals[i]); @@ -131,6 +135,15 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) { Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1); Toy_initLiteralDictionary(dictionary); + //preallocate enough space + dictionary->capacity = TOY_AS_DICTIONARY(original)->capacity; + dictionary->entries = TOY_ALLOCATE(Toy_private_dictionary_entry, dictionary->capacity); + + for (int i = 0; i < dictionary->capacity; i++) { + dictionary->entries[i].key = TOY_TO_NULL_LITERAL; + dictionary->entries[i].value = TOY_TO_NULL_LITERAL; + } + //copy each entry for (int i = 0; i < TOY_AS_DICTIONARY(original)->capacity; i++) { if ( !TOY_IS_NULL(TOY_AS_DICTIONARY(original)->entries[i].key) ) { @@ -168,7 +181,7 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) { return original; //literally a shallow copy } - case TOY_LITERAL_ARRAY_INTERMEDIATE: { + case TOY_LITERAL_ARRAY_INTERMEDIATE: { //TODO: efficient preallocation? Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); Toy_initLiteralArray(array); @@ -184,7 +197,7 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) { return ret; } - case TOY_LITERAL_DICTIONARY_INTERMEDIATE: { + case TOY_LITERAL_DICTIONARY_INTERMEDIATE: { //TODO: efficient preallocation? Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); Toy_initLiteralArray(array); @@ -200,7 +213,7 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) { return ret; } - case TOY_LITERAL_TYPE_INTERMEDIATE: { + case TOY_LITERAL_TYPE_INTERMEDIATE: { //TODO: efficient preallocation? Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); Toy_initLiteralArray(array);