TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Curious lack of sprintf scaling

204 点作者 markdog12大约 3 年前

24 条评论

greggman3大约 3 年前
why is locale stuff even in sprintf? What things get localized? Dates? Line endings?<p>I&#x27;m probably dumb but one of things that bugs me with various libraries is when someone has made the decision to do something high level at a low level. For example, localizing inside sprintf,<p>An another example might be an unzip library (read a zip file). Ideally the library should be small IMO. The simplest might you you pass it a bucket of bytes. If you want to make it flexible then you pass it some abstract interface (or 1-2 functions + void* userdata) so you can supply a &quot;read(byteOffset, length)&quot;. You can then provide, outside of the library, streamed files, stream networking, etc...<p>But, bad libraries (bad IMO) will instead provide like 12 overrides &quot;unzip(void* bytes), unzip(const char* filename), unzip(socket), unzip(url)&quot; and end up including the world in their library. This kind of &quot;try to do everything&quot; is extremely common in npm libraries :( I don&#x27;t need your library to include command line parsing! If you want to make a tool, make a library, then make a separate tool that uses that library. Keep the 2 separated so users of the library don&#x27;t need dependencies that only the tool needs. (probably the most common npm example but there are lots of others)<p>Really surprised something as low-level as sprintf needs locale. Even streams I&#x27;d expect maybe a Date object would but not the stream itself.
评论 #30473554 未加载
评论 #30474565 未加载
评论 #30474588 未加载
评论 #30473798 未加载
评论 #30474271 未加载
评论 #30473539 未加载
评论 #30473576 未加载
评论 #30474755 未加载
评论 #30473826 未加载
评论 #30474153 未加载
formerly_proven大约 3 年前
C&#x2F;C++ locales are a trashfire. The path to enlightenment is to not use them and discard all libraries which think they can get away with calling setlocale (which a few do, but is more or less a given when we&#x27;re talking about GUIs).<p>&gt; obviously you should not use sprintf, you should use C++ iostreams<p>Friends don&#x27;t let friends use iostreams.
评论 #30473681 未加载
评论 #30473479 未加载
garaetjjte大约 3 年前
If you want to read rant about setlocale, highly recommended: <a href="https:&#x2F;&#x2F;github.com&#x2F;mpv-player&#x2F;mpv&#x2F;commit&#x2F;1e70e82baa9193f6f027338b0fab0f5078971fbe" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;mpv-player&#x2F;mpv&#x2F;commit&#x2F;1e70e82baa9193f6f02...</a>
评论 #30473971 未加载
评论 #30473482 未加载
EdSchouten大约 3 年前
I think the only reasonable solution is to completely deprecate functions like setlocale(). Software should just use _l() functions if they want something localised.<p>Global state considered harmful.
评论 #30473074 未加载
评论 #30473268 未加载
评论 #30473097 未加载
MobiusHorizons大约 3 年前
Excuse the lack of context here, I haven&#x27;t dealt much with locale&#x27;s in C, and I&#x27;m probably showing my ignorance.<p>Why would you ever mutate a locale object? Is that the common way to change locales in C? Wouldn&#x27;t it make more sense to have locale objects be roughly immutable? It doesn&#x27;t seem like they should have any real reason to change very often in a typical use-case. I would think any given person only has a small (1-3 or so) number of locale&#x27;s they use on any regular basis.<p>Are locale objects being mutated really common enough that you need a mutex to protect against accidentally rendering something in the wrong locale?
评论 #30473292 未加载
matheist大约 3 年前
I ran into sprintf&#x27;s dependence on locale recently when trying to use it in a WebAssembly module. Since I was compiling for the browser, I wanted to not depend on locale. Even setting aside the locale stuff, the wasi sdk still wanted to pull in file-related things like read&#x2F;write&#x2F;seek. I just wanted to do formatted print to a pre-existing buffer.<p>I ended up using nanoprintf — it&#x27;s a single header file and in the public domain.<p>(<a href="https:&#x2F;&#x2F;github.com&#x2F;charlesnicholson&#x2F;nanoprintf" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;charlesnicholson&#x2F;nanoprintf</a>)
评论 #30481997 未加载
markdog12大约 3 年前
Anyone reading this will probably also be interested in his related post: <a href="https:&#x2F;&#x2F;aras-p.info&#x2F;blog&#x2F;2022&#x2F;02&#x2F;03&#x2F;Speeding-up-Blender-.obj-export&#x2F;" rel="nofollow">https:&#x2F;&#x2F;aras-p.info&#x2F;blog&#x2F;2022&#x2F;02&#x2F;03&#x2F;Speeding-up-Blender-.obj...</a>
bla3大约 3 年前
&gt; And no, usual Internet advice of “MSVC sucks, use Clang”<p>Given that this talks about a problem in the Microsoft standard library, wouldn&#x27;t the usual internet advice be &quot;use clang, and also llvm&#x27;s libc++&quot;? If clang just compiles the same slow code as msvc, it won&#x27;t magically make it fast.
评论 #30474167 未加载
diekhans大约 3 年前
Has this been reported to apple? One would think they would pay attention to something that makes the M1 look slow it it reaches the right people.<p>I18N was one of the few things POSIX didn&#x27;t do well. Have an environment variable change the sort command causes lots grief.
评论 #30474795 未加载
评论 #30474512 未加载
fwsgonzo大约 3 年前
fmt is a must if you can get away with using it. On smaller systems you should try strf, as it produces very small memory footprint and doesn&#x27;t blow up your binaries. It is 5x smaller than fmt in footprint.
bborud大约 3 年前
Locale in library functions in general is an example of solving problems at the wrong abstraction level. It also breaks the fundamental idea of how shell tools are meant to be usable in unix. If they don&#x27;t have stable outputs, then they become unusable.<p>(We had to create a set of locale-resistant and consistent versions of shell tools for a system that made heavy use of shell tools to process large amounts of data across thousands of machines. All you needed was one misconfigured locale on one machine and the result would be chaos).<p>You pay the cost every time rather than when you actually care about it. And when you really don&#x27;t want locale to interfere it still comes back to haunt you if you don&#x27;t pay special attention to it. (Remember how Python had locale-dependent XML-RPC that made sure two machines with different ways of formatting floats behaved?).<p>Locale is bad design. Very bad design.
addaon大约 3 年前
I wonder if the original export code that lead to this investigation was actually correct? It sounds like sprintf() was being called without an explicit locale. This can be fine if Blender does a top-level setlocale(), but can also be subtly and horrible unfine otherwise...<p>Sounds like there&#x27;s plenty of opportunity for library-level improvements here (as well as application-level workarounds), but certainly the sprintf_l(..., locale, ...) being slow is the most surprising to me, and likely the easiest to fix.
评论 #30472996 未加载
rurban大约 3 年前
I&#x27;ve recently implemented the secure variant without any locale support. Took me a day. Now just the secure scanf family is missing, and this needs locale support unfortunately.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;rurban&#x2F;safeclib&#x2F;blob&#x2F;master&#x2F;src&#x2F;str&#x2F;vsnprintf_s.c" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;rurban&#x2F;safeclib&#x2F;blob&#x2F;master&#x2F;src&#x2F;str&#x2F;vsnpr...</a>
eyelidlessness大约 3 年前
Particulars aside, the pathology is exactly what I’d expect from low level manually managed memory languages. Oh you want a multithreaded abstraction without a VM or GC and you want it to just work? It’s going to do a lot of extra work or it’s gonna be the next “logging failboat” or both.
trulyme大约 3 年前
&gt; I only have an Ubuntu 20 install via WSL2 here to test, and using the default compilers there (clang 10 and gcc 9.3), things look pretty nice:<p>WSL2 is not that bad, but installing a real Linux in a VM takes about 10 minutes, so this seems a weird thing to say.
评论 #30475930 未加载
Unit520大约 3 年前
Reading this article motivated me to take a closer look at printf&#x2F;iostreams alternatives, and I have to say, the mentioned {fmt} library finally made me switch, so thanks for that!
thaumasiotes大约 3 年前
&gt; So given all this knowledge, presumably, if each thread used a physically different locale object and snprintf_l, then it would scale fine. And it does:<p>The author provides several graphs in which what appears to be the total execution time stays constant as the number of threads varies, and this is described as &quot;good scaling&quot;.<p>How do I know what&#x27;s being graphed is the total execution time?<p>&gt; Converting two million numbers into strings takes 100 milliseconds when one CPU core is doing it. When all eight “performance” cores are doing it, it takes 1.8 seconds, or 18 times as long.<p>This corresponds to a curve where &quot;one core&quot; takes the value 100 and &quot;8 cores&quot; takes the value 1866.<p>But isn&#x27;t constant execution time as we increase from one thread to eight threads <i>terrible scaling</i>? What&#x27;s happening here?
评论 #30475285 未加载
nec4b大约 3 年前
I don&#x27;t think author understands what zero cost abstraction means. He does have a point about c++ standard library still being a hit or a miss regarding performance.
fyrn-大约 3 年前
This would really benefit from labeling the y Axis
评论 #30473201 未加载
评论 #30473193 未加载
peapicker大约 3 年前
Curious that strtol() etc wasn’t profiled as this concerns turning ints into strings. Snprintf has a lot of other overhead.
PandaPanda150大约 3 年前
Classic use-case where a posix rwlock will outperform a mutex.<p>How often does the locale change in practice? Almost never.
评论 #30473516 未加载
评论 #30473706 未加载
pjmlp大约 3 年前
Very nice article, although the jabs at zero cost abstractions are out of place.<p>Bjarne has always used the expression to mean it doesn&#x27;t cost more than if the same code has been manually written by hand.<p>An Assembly written version of iostreams, with the same architecture, would perform the same.
sirwhinesalot大约 3 年前
Today in why global variables are bad...
kjgkjhfkjf大约 3 年前
TL;DR sprintf has to acquire a lock to access some shared data so the multiple CPUs can&#x27;t operate concurrently.