-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added StringBuilder class #10860
added StringBuilder class #10860
Conversation
816fd31
to
5722eb1
Compare
e7b4add
to
02db945
Compare
core/string_builder.h
Outdated
|
||
class StringBuilder : public Reference { | ||
GDCLASS(StringBuilder, Reference) | ||
private: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private
is unnecessary here.
02db945
to
3cb06bd
Compare
Would be great if we could specify a custom bucket size. For example, for a bindings generator I know I will append a lot, so I would benefit from a bigger bucket. |
core/string_builder.h
Outdated
|
||
#include "core/ustring.h" | ||
|
||
#define BUCKET_SIZE 32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better put this in an anonymous enum, no need to pollute the #define space with a generic macro name
core/string_builder.h
Outdated
}; | ||
|
||
uint32_t string_length = 0; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably too complex and both String and const char * are really small (both 8 bytes), and have no initialization/freeing cost if empty, so i would just do:
struct StringData {
String string;
cosnt char* cstring; //if not null, use this, otherwise use string.
}; // should be at most 16 bytes, which is tiny
Vector<StringData> strings; //resizes every powers of 2, so this is should already be more efficient and cache local than buckets
core/string_builder.h
Outdated
|
||
#define BUCKET_SIZE 32 | ||
|
||
class StringBuilder : public Reference { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Object is a pretty fatty class, which lots of code for initializing/deinitializing, using it would beat the purpose and it would just be faster to use this as a local class.
3cb06bd
to
bb7af10
Compare
Is it possible to re-use the StringBuilder? (random question, I just know the C# one can by setting Length back to 0) Also is it planned to have it available in GDScript? (oh wait if it's not an Object then it can't...) |
@Zylann currently it can't be reused. I could implement a I had it be a |
The re-using feature was a bit related to inheriting Object though, but I understand it can be useless when used on the engine side |
core/string_builder.cpp
Outdated
|
||
const char *s = c_strings[c_string_elem]; | ||
|
||
String converted_string = String::utf8(s, appended_strings[i]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should not assume that this is utf8. Godot simply does not have this datatype around in this format, as it's always converted when parsed. I would assume it a regular ascii C string. and copy char -> wchar_t with a for() loop. It will be much faster for existing use cases we intend to use this for.
bb7af10
to
80ce82b
Compare
When doing large string concatenations the default push_back on the String class can slow down things quite a bit. This is because it has to constantly reallocate the memory and copy the contents. This StringBuilder class delays the concatenation until the size of the resulting string is known.
80ce82b
to
95a0886
Compare
Hello there, I came from #10844. My PR will likely depend on the StringBuffer here, so I kinda want to request a few optimizations.
So, it'll store everything in Also, it would be nice to have Well, I know this is quite a request) If something of this will be done, that's nice. If I got the "go ahead" to implement all these things in my PR, that would be nice too) The point that I really need these optimizations to use |
@MednauN I see, I made the StringBuilder with the shader compiler and the code that GDNative and mono/C# need to generate in mind, so it tries to minimize allocations until you need the final string. You want a StringBuffer, which is a bit different. I can add one of those too if @reduz is not against it, but as I said, this was made with huge strings in mind, not constructing small ones. |
@karroffel I don't see though how @MednauN's suggestions contradict or worsen the use case of constructing large strings, and it's better not to increase the number of entities when you can. |
@endragor his implementation is basically a buffer which you can write to. This is not any better than just using You don't win anything over My implementation saves pointers to the data. If you append more data then you might need to copy the pointers around, but you don't copy the data itself. So in essence:
That said, I could add such a small buffer, but it's not really the purpose of that data structure. What this I'd rather add a |
When doing large string concatenations the default push_back on the
String class can slow down things quite a bit. This is because it
has to constantly reallocate the memory and copy the contents. This
StringBuilder class delays the concatenation until the size of the
resulting string is known.