#string #inline #inlinable #avoid

no-std inlinable_string

The inlinable_string crate provides the InlinableString type – an owned, grow-able UTF-8 string that stores small strings inline and avoids heap-allocation – and the StringExt trait which abstracts string operations over both std::string::String and InlinableString (or even your own custom string type)

14 releases

0.1.15 Jan 4, 2022
0.1.14 Nov 29, 2020
0.1.11 Feb 4, 2020
0.1.10 May 15, 2018
0.1.3 Dec 2, 2015

#74 in Rust patterns

Download history 58557/week @ 2024-07-04 59276/week @ 2024-07-11 63969/week @ 2024-07-18 62999/week @ 2024-07-25 65454/week @ 2024-08-01 67342/week @ 2024-08-08 62913/week @ 2024-08-15 67007/week @ 2024-08-22 69107/week @ 2024-08-29 70628/week @ 2024-09-05 69868/week @ 2024-09-12 64596/week @ 2024-09-19 66005/week @ 2024-09-26 72846/week @ 2024-10-03 72887/week @ 2024-10-10 78734/week @ 2024-10-17

304,852 downloads per month
Used in 528 crates (12 directly)

Apache-2.0/MIT

77KB
1.5K SLoC

inlinable_string

Build Status

Coverage Status

The inlinable_string crate provides the InlinableString type — an owned, grow-able UTF-8 string that stores small strings inline and avoids heap-allocation — and the StringExt trait which abstracts string operations over both std::string::String and InlinableString (or even your own custom string type).

StringExt's API is mostly identical to std::string::String; unstable and deprecated methods are not included. A StringExt implementation is provided for both std::string::String and InlinableString. This enables InlinableString to generally work as a drop-in replacement for std::string::String and &StringExt to work with references to either type.

But is it actually faster than using std::string::String?

Here are some current (micro)benchmark results. I encourage you to verify them yourself by running cargo bench --feature nightly with a nightly Rust! I am also very open to adding more realistic and representative benchmarks! Share some ideas with me!

Constructing from a large &str:

test benches::bench_inlinable_string_from_large                ... bench:          32 ns/iter (+/- 6)
test benches::bench_std_string_from_large                      ... bench:          31 ns/iter (+/- 10)

Constructing from a small &str:

test benches::bench_inlinable_string_from_small                ... bench:           1 ns/iter (+/- 0)
test benches::bench_std_string_from_small                      ... bench:          26 ns/iter (+/- 14)

Pushing a large &str onto an empty string:

test benches::bench_inlinable_string_push_str_large_onto_empty ... bench:          37 ns/iter (+/- 12)
test benches::bench_std_string_push_str_large_onto_empty       ... bench:          30 ns/iter (+/- 9)

Pushing a small &str onto an empty string:

test benches::bench_inlinable_string_push_str_small_onto_empty ... bench:          11 ns/iter (+/- 4)
test benches::bench_std_string_push_str_small_onto_empty       ... bench:          23 ns/iter (+/- 10)

Pushing a large &str onto a large string:

test benches::bench_inlinable_string_push_str_large_onto_large ... bench:          80 ns/iter (+/- 24)
test benches::bench_std_string_push_str_large_onto_large       ... bench:          78 ns/iter (+/- 23)

Pushing a small &str onto a small string:

test benches::bench_inlinable_string_push_str_small_onto_small ... bench:          17 ns/iter (+/- 6)
test benches::bench_std_string_push_str_small_onto_small       ... bench:          60 ns/iter (+/- 15)

TLDR: If your string's size tends to stay within INLINE_STRING_CAPACITY, then InlinableString is much faster. Crossing the threshold and forcing a promotion from inline storage to heap allocation will slow it down more than std::string::String and you can see the expected drop off in such cases, but that is generally a one time cost. Once the strings are already larger than INLINE_STRING_CAPACITY, then the performance difference is negligible. However, take all this with a grain of salt! These are very micro benchmarks and your (hashtag) Real World workload may differ greatly!

Install

Either

$ cargo add inlinable_string

or add this to your Cargo.toml:

[dependencies]
inlinable_string = "0.1.0"

Documentation

Documentation

Dependencies

~165KB