Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Considering use of stb_sprintf #1038

Closed
itamago opened this issue Feb 25, 2017 · 8 comments
Closed

Considering use of stb_sprintf #1038

itamago opened this issue Feb 25, 2017 · 8 comments

Comments

@itamago
Copy link

itamago commented Feb 25, 2017

Hello,

stb_sprintf is a good replacement for sprintf, snprintf, vsprintf, and vsnprintf.
The 2 main reasons are performances (see the benchmarks in the file), and having the exact same behaviour on every platform.

One remaining issue is the implementation of vsnprintf which doesn't return the standard value. Usually, people use vsnprintf(NULL, 0, ...) to estimate the required buffer size, and then use vsnprintf(buffer, size, ...) to convert. In the current implementation, vsnprintf(NULL, 0, ...) always returns 0 (instead of returning the number of bytes required).

For ImGui, using stb_sprintf.h would ensure having the same results on every platforms.

@itamago
Copy link
Author

itamago commented Feb 25, 2017

The current performances (as of Feb2017) are those :

PERFORMANCE vs MSVC 2008 32-/64-bit (GCC is even slower than MSVC):
"%d" across all 32-bit ints (4.8x/4.0x faster than 32-/64-bit MSVC)
"%24d" across all 32-bit ints (4.5x/4.2x faster)
"%x" across all 32-bit ints (4.5x/3.8x faster)
"%08x" across all 32-bit ints (4.3x/3.8x faster)
"%f" across e-10 to e+10 floats (7.3x/6.0x faster)
"%e" across e-10 to e+10 floats (8.1x/6.0x faster)
"%g" across e-10 to e+10 floats (10.0x/7.1x faster)
"%f" for values near e-300 (7.9x/6.5x faster)
"%f" for values near e+300 (10.0x/9.1x faster)
"%e" for values near e-300 (10.1x/7.0x faster)
"%e" for values near e+300 (9.2x/6.0x faster)
"%.320f" for values near e-300 (12.6x/11.2x faster)
"%a" for random values (8.6x/4.3x faster)
"%I64d" for 64-bits with 32-bit values (4.8x/3.4x faster)
"%I64d" for 64-bits > 32-bit values (4.9x/5.5x faster)
"%s%s%s" for 64 char strings (7.1x/7.3x faster)
"...512 char string..." ( 35.0x/32.5x faster!)

@MrSapps
Copy link

MrSapps commented Feb 25, 2017

I'm guessing its missing debug checks or something? Seems strange how it could be so much faster yet still handle all of the same cases.

@Wohlstand
Copy link

Wohlstand commented Feb 25, 2017

Try GCC 5.3, and I guess you even built code in debug mode. You must build both benchmarks in release mode (for the gcc you must use the -O2 flag, or result will be built in debug mode, therefore it will be slower). In other side are was benchmarks are showing that MinGW built apps are giving faster result than MSVC's.

The case of MinGW it has own independent runtime (reason of bigger size of binaries, especially if you will use -static-libgcc and -static-libstdc++) which allows you to build app even for Windows 95 (if you will don't use unsupported functions in it), and the minimal supported Windows version is dependent of that which WinAPI functions you are using.

@itamago
Copy link
Author

itamago commented Feb 25, 2017

In case of ImGui, the biggest stake is not the performance, but having the exact same behaviour on each platform.

@ocornut
Copy link
Owner

ocornut commented Feb 25, 2017

I yet have to evaluate stb_printf but knowing the RAD guys I'm sure it is super efficient.

I guess we could make it optional for a start, e.g. add a imconfig.h option where the user would need to add:

#include <stb_sprintf.h>
#define IMGUI_USE_STB_SPRINTF

If the function signature are the same we can then use add some #ifdef+#define at the top of imgui.cpp?

#ifdef IMGUI_USE_STB_SPRINTF
#undef vsnprintf
#define vsnprintf stbsp_vsnprintf

?

@itamago
Copy link
Author

itamago commented Feb 26, 2017

Yes, the signatures are the same.
But keep in mind the function vsnprintf doesn't return the same values than the standard (for the moment) ; I checked the use in ImGui, and it doesn't seem to impact it.
(Here is the discussion about standard behaviour of vsnprintf : nothings/stb#408)

@ocornut
Copy link
Owner

ocornut commented Oct 24, 2017

@itamago @paniq

I have pushed this small change:

If you set #define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS in imconfig.h it will remove the implementation of ImFormatString/ImFormatStringV so you can implement them yourself.

I think this solves the issue described in this thread without having to bother with trying to match exact prototypes between, e.g. vsnprintf and stbsp_vsnprintf.

If you have time to check it out, could you let me know if it works for you, in particular with stbsp_vsnprintf ? And if you can paste in your implementation of ImFormatString/ImFormatStringV using the stb code it'll be great. Thanks!

Note that the only piece of code in dear imgui relying on passing a NULL first parameter is ImGuiTextBuffer::appendv() which is a general purpose "long string builder" used by clipboard logging (LogToClipboard function), and the Log demo. And the double sprintf call could probably be improved. I haven't looked at stb_printf but if we can change the ImFormatString/ImFormatStringV specs to make code like ImGuiTextBuffer::appendv more efficient it would be great.

ocornut added a commit that referenced this issue Nov 19, 2019
…T_FORMAT_STRING_FUNCTIONS. (#1038)

Renamed IMGUI_DISABLE_MATH_FUNCTIONS to IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS.
@ocornut
Copy link
Owner

ocornut commented Nov 19, 2019

(repost with fixed typos)
Everyone please note that I have renamed IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS to IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS for consistency.
I made it that IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS will error during build to facilitate fixing for the change:

#ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS                // Renamed in 1.74
#error Use IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
#endif

Also closing this topic as it's pretty much supported now, and there's even a helper IMGUI_USE_STB_SPRINTF that perform the wrapping automatically in imgui.h if used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants