String Library Comparisons |
Features |
This table is not complete, and may have inaccurate entries. Please send me feedback if you have any corrections or any feedback on this table.
The total score is computed by scoring greens at 100%, blues at 66.7%, oranges at 33.3%, and reds at 0%, ignoring whites, and taking a straight average of these scores for each library.
These "scores" should definately be taken with a grain of salt. The fact that Ropes is incomplete should be fatal to it, and pretty much take it out of consideration, and clearly some features should be considered with different levels of importance. Nevertheless, there's a strong case to be made that firestring, MS's Strsafe, c2lib and libclc are either worse or not significantly better than the standard library. The other libraries/solutions are worth switching to and Bstrlib distinguishes itself.
Thread safety - this means that a modification of a string in one
thread and reading or modification of any different string in another thread
will not lead to any other problems. But further strings must be sharable
between threads using standard threading mechanisms. std::string is not
necessarily unsafe, however, the standard does not require it, and in popular
implementations actually is not.
Usable in C, C++ API - Its a little unfair to ding Python and Java for
not having C/C++ support, as they are different languages.
International Support - To be universal, one should be able to accept
unicode 4.0 and convert between the transfer formats.
Ref substrings - An ability to specify an arbitrary substring from an
initial string without copying its contents or modifying the initial string.
Closure safety - This means that all outputs can be used as legal
inputs to the library.
Parameter check - Parameters are checked for safety either via
language type safety and/or runtime content checking, and errors lead to a
well defined outcome.
Performance Benchmarks |
Important Note: For Bstrlib to perform well, it is required that the compiler optimization settings for it be set to a reasonable maximum performance setting. For most compilers this corresponds to a flag such as "-O2". The point being that the compiler's standard library has already been compiled this way, and thus to be a fair test, Bstrlib should be compiled to match the standard library's optimizations.
Here are some performance numbers of CBString relative to STL. Note that most STL implementations use a lazy deferred default constructor strategy which makes STL far faster than CBString for default constructions. However for inner loop methods, the CBString architecture is generally superior as seen below.
Performance of CBString over std::string
Based on cppbench.cpp example.
|
Note that STL Port does not perform bounds checking which is why it does so well with character extraction versus CBString (changing the CBString test to cast to const char * first, then extract raises CBString's performance to 100% of STL Port for this test). Microsoft's STL (which Intel also uses) has implemented concat as an O(m+n) algorithm which is why it performs so poorly versus the O(m) algorithm in CBString.
Here are some performance numbers of Bstrlib relative to standard char * C library functions.
Performance of Bstrlib C API over standard char * Clib functions
Based on cbench.c example.
|
With the exception of concatenation, C appears to be more competitive with Bstrlib's C API, than STL under C++ is with Bstrlib's C++ API. However, it is difficult to ignore the rather stunning difference in concatenation performance.
Here are some performance numbers of Bstrlib relative to the CString class from Microsoft's Foundation Classes.
Performance of CBString over MFC's CString
Based on mfcbench.cpp example.
|
Note that MFC's CString does not perform bounds checking which is why it does so well with character extraction versus CBString. When switching to a more comparable unsafe character extraction test, the performance is substantially the same. Note that CString does not have a "replace" method that is comparable to the one used in CBString or STL's std::string, so it was required to simulate it with a delete-insert pair.