C++ code that passes strings through multiple function layers (parsing, validation, transformation) where each function takes const std::string& or std::string. Even with const&, callers with string literals or substrings must construct a temporary std::string, triggering heap allocation. The metric was throughput of a text parsing pipeline processing millions of short strings.
Replacing const std::string& parameters with std::string_view in functions that only read (never store or modify) the string. string_view is a non-owning (pointer, length) pair — 16 bytes, always on the stack, zero allocation. It binds to std::string, const char*, string literals, and substrings without any copy or allocation.
For a CSV parser calling 6 functions per field (validate, trim, classify, transform, hash, store), switching the first 5 functions from const string& to string_view eliminated 5 temporary string allocations per field. On a 500MB CSV with 50M fields, parsing throughput improved 1.9x.
| Parameter Type | Parse Throughput (MB/s) | Heap Allocs/field |
|---|---|---|
| const string& | 180 | 6 |
| string_view (read path) | 340 | 1 (final store only) |
// BEFORE: every call site may allocate
bool validate(const std::string& field);
std::string trim(const std::string& field);
// AFTER: zero-allocation read path
bool validate(std::string_view field);
std::string_view trim(std::string_view field); // return view into original buffer
// Substring without allocation:
std::string_view line = "name,age,city";
auto field = line.substr(5, 3); // "age" — no allocation, just pointer arithmetic
// DANGER: string_view must not outlive the data it points to
std::string_view dangling() {
std::string temp = compute();
return temp; // BUG: temp destroyed, view dangles
}- Replacing parameters that store the string: Functions that save the string into a member variable or container still need
std::string(ownership). Usingstring_viewthere requires an explicit conversion (std::string(sv)), which allocates anyway — but now the allocation is hidden and easy to miss. - string_view for null-terminated C APIs:
string_viewis not null-terminated. Passing.data()to C functions expecting null termination is undefined behavior unless the view happens to point at a null-terminated source.
C++17 (where std::string_view was introduced). Applies to all implementations. GCC/Clang/MSVC all optimize string_view to two registers.