Code Size Analysis#

pw_string: Efficient, easy, and safe string manipulation

Save code space by replacing snprintf#

The C standard library function snprintf is commonly used for string formatting. However, it isn’t optimized for embedded systems, and using it will bring in a lot of other standard library code that will inflate your binary size.

Size comparison: snprintf versus pw::StringBuilder#

The fixed code size cost of pw::StringBuilder is smaller than that of std::snprintf. Using only pw::StringBuilder’s << and append methods instead of snprintf leads to significant code size reductions.

However, there are cases when the incremental code size cost of pw::StringBuilder is similar to that of snprintf. For example, each argument to pw::StringBuilder’s << method expands to a function call, but one or two pw::StringBuilder appends may still have a smaller code size impact than a single snprintf call. Using pw::StringBuilder error handling will also impact code size in a way that is comparable to snprintf.

Label

Segment

Delta

Total StringBuilder cost when used alongside snprintf

FLASH

+44

[section .code]

-2

_ctype_

+4

quorem

+2

__mprec_tens

+4

main

+4

p05.0

NEW

+698

__udivmoddi4

NEW

+244

pw::string_internal::InitializeStringBuffer<>()

NEW

+220

pw::string::IntToString<>()

NEW

+168

pw::string::internal::kPowersOf10

NEW

+74

pw::StringBuilder::append()

NEW

+60

pw::StringBuilder::ResizeAndTerminate()

NEW

+26

pw::StringBuilder::NullTerminate()

NEW

+20

pw::StringBuilder::HandleStatusWithSize()

NEW

+2

__aeabi_ldiv0

+1,568

StringBuilder cost when completely replacing snprintf

FLASH

+55

[section .code]

DEL

-504

_svfprintf_r

-3

_ctype_

+4

quorem

-8

__mprec_tens

DEL

-184

__ssputs_r

DEL

-104

snprintf

+4

main

DEL

-66

__wrap_realloc

+2

pw::allocator::BucketBlockAllocator<>::ReserveBlock()

-4

p05.0

DEL

-8

__wrap__realloc_r

NEW

+698

__udivmoddi4

NEW

+244

pw::string_internal::InitializeStringBuffer<>()

NEW

+220

pw::string::IntToString<>()

NEW

+168

pw::string::internal::kPowersOf10

NEW

+74

pw::StringBuilder::append()

NEW

+60

pw::StringBuilder::ResizeAndTerminate()

NEW

+26

pw::StringBuilder::NullTerminate()

NEW

+20

pw::StringBuilder::HandleStatusWithSize()

NEW

+2

__aeabi_ldiv0

+696

Incremental cost relative to snprintf for 10 strings

FLASH

-40

[section .code]

-64

main

+56

pw::StringBuilder::operator<< <>()

NEW

+8

pw::StringBuilder::push_back()

-40

Size comparison: snprintf versus pw::string::Format#

The pw::string::Format functions have a small, fixed code size cost. However, relative to equivalent std::snprintf calls, there is no incremental code size cost to using pw::string::Format.

Label

Segment

Delta

Format instead of snprintf once, return size

FLASH

-4

quorem

DEL

-104

snprintf

-12

pw::string::OutputStringsToBuffer()

NEW

+88

_vsnprintf_r

NEW

+56

pw::string::FormatVaList()

NEW

+36

pw::string::Format()

NEW

+28

vsnprintf

+88

Format instead of snprintf 10 times, handle errors

FLASH

+4

[section .code]

-32

pw::string::OutputStringsToBuffer()

DEL

-104

snprintf

DEL

-44

(anonymous namespace)::ProcessResult()

NEW

+88

_vsnprintf_r

NEW

+56

pw::string::FormatVaList()

NEW

+36

pw::string::Format()

NEW

+28

vsnprintf

+32

Format instead of snprintf 50 times, no error handling

FLASH

-8

pw::string::OutputStringsToBuffer()

DEL

-104

snprintf

NEW

+88

_vsnprintf_r

NEW

+56

pw::string::FormatVaList()

NEW

+36

pw::string::Format()

NEW

+28

vsnprintf

+96