I’d be more interested in “this is faster than X” claims if it does a fair comparison - pushing the implementation out of the header. Otherwise (depending on operation) inlining ends up significantly throwing off performance numbers. That said it’s much easier to make faster than libN string libraries if you don’t have abi constraints to deal with. This uses any value struct to hold much of its metadata which causes…
Rapidstring: Maybe the fastest string library ever
31–40 of 62 posts
Re: Rapidstring: Maybe the fastest string library ever
#32I like the stack trick. But it's still just a membuf library, without any string support. No encoding, no Unicode, no upper/lower/fc/norm support, which would be important to compare or find strings. And coreutils (e.g grep) still have no unicode support. It's 2018, not the seventies anymore. Unicode strings need to be normalized to be able to be found.
Just like the strings in the C and C++ standard library.
Re: Rapidstring: Maybe the fastest string library ever
#33Earlier quoted context omitted.
Unicode is supported with UTF-8, only different character types aren't supported because generics are messy in C. I thought of accepting void* to support wchar_t and others, but some performance penalties came with it so I decided against it.
No, having different character types (I believe you are referring to C11's `char16_t` and `char32_t`?) is not a requirement for Unicode support. At the very least you need to have a single function or two that... * Receives a string expected to be encoded in UTF-8, and an offset to it expected to be a UTF-8 sequence boundary. * Scans forward or backward for the next or previous UTF-8 sequence boundary. * Optionally r…
Re: Rapidstring: Maybe the fastest string library ever
#34Earlier quoted context omitted.
It appears to support Unicode just fine, you just have to use UTF-8. I find that in most cases you should only use UTF-8 anyway, so in most cases that is not a problem.
If you're using WinAPI, you have to use UCS-16. Converting strings for every call would be abysmal to performance.
Re: Rapidstring: Maybe the fastest string library ever
#35Re: Rapidstring: Maybe the fastest string library ever
#36Hi, John! Why did you chose to store 'size' and 'capacity' in the 'rs_heap' struct instead of at the beginning of the heap-allocated buffer pointed to by 'buffer'? Did you find it was preferable to have a larger 'rs_heap'?
Why would you store the size and capacity as part of the buffer? It makes the buffer more complex (you need a separate unsized struct or some mess special-casing the first 16 bytes or so), wastes heap size, requires dereferencing before you can even check on size & capacity, and makes SSO harder/more limited.
AFAIK both C++'s std::string and Rust's String store size and capacity on the stack, separate from the buffer.
Re: Rapidstring: Maybe the fastest string library ever
#37Earlier quoted context omitted.
No, having different character types (I believe you are referring to C11's `char16_t` and `char32_t`?) is not a requirement for Unicode support. At the very least you need to have a single function or two that... * Receives a string expected to be encoded in UTF-8, and an offset to it expected to be a UTF-8 sequence boundary. * Scans forward or backward for the next or previous UTF-8 sequence boundary. * Optionally r…
I don't see any functions in the OP's library that would require dedicated UTF-8 handling. The string length is given in bytes, not characters or codepoints. There's no functionality to give you the character at n-th location etc... you can easily implement all UNICODE-specific functionality in a separate library and use it together with the OPs library. IMHO that's even preferable.
And it's not easy. I implemented the third of its kind. First there was ICU, which is overly bloated. You don't need 30MB for a simple string libc. Then there is libunistring which has overly slow iterators, so not usable for coreutils. And then there's my safelibc, which is small and fast, but only for wide-chars, not utf-8.
I fixed and updated the musl case-mapping, making it 2x faster, but this is not in yet. And there's not even a properly spec'ed wcscmp/wcsicmp to find strings. glibc is an overall mess. I won't touch that. wcsicmp/wcsfc/wcsnorm are not even in POSIX.
Re: Rapidstring: Maybe the fastest string library ever
#38Earlier quoted context omitted.
In the modern development environment, I think it's genuinely fair to say that something which doesn't support Unicode strings cannot be claimed to support strings. It's like saying you have the fastest integer math library ever written, with the minor caveat that it only supports numbers smaller than 256 because it achieves that speed by being simply a hardcoded lookup table, and crashes if you give it anything else…
It appears to support Unicode just fine, you just have to use UTF-8. I find that in most cases you should only use UTF-8 anyway, so in most cases that is not a problem.
And with case-insensitivity it gets worse, as there are some locale dependent additional rules, for Turkish and Lithuania. And this depends on "some" global settings.
Re: Rapidstring: Maybe the fastest string library ever
#39I like the stack trick. But it's still just a membuf library, without any string support. No encoding, no Unicode, no upper/lower/fc/norm support, which would be important to compare or find strings. And coreutils (e.g grep) still have no unicode support. It's 2018, not the seventies anymore. Unicode strings need to be normalized to be able to be found.
> But it's still just a membuf library, without any string support. Just like the strings in the C and C++ standard library.
It's a mess and a big security risk. We are still in the stone age of string support.
Re: Rapidstring: Maybe the fastest string library ever
#40Hi, John! Why did you chose to store 'size' and 'capacity' in the 'rs_heap' struct instead of at the beginning of the heap-allocated buffer pointed to by 'buffer'? Did you find it was preferable to have a larger 'rs_heap'?
> Why did you chose to store 'size' and 'capacity' in the 'rs_heap' struct instead of at the beginning of the heap-allocated buffer pointed to by 'buffer'? Why would you store the size and capacity as part of the buffer? It makes the buffer more complex (you need a separate unsized struct or some mess special-casing the first 16 bytes or so), wastes heap size, requires dereferencing before you can even check on size…
To decrease the memory footprint of your small strings. It can see how some uses cases where a large proportion of strings are very small would benefit from it.
I was just curious to know if that design decision was based on analysis of a real use case, or if it was due to a compatibility issue or something.