digitalmars.D - std.conv.to!string(float) Is too heavy
- Hipreme (20/20) Oct 12 2021 I have wrote a simple hello world using std.conv:
- IGotD- (8/12) Oct 12 2021 I've seen similar effects, not only with std.conv but with other
- user1234 (10/30) Oct 12 2021 You compare apples and oranges. Convertion from integer types to
- Hipreme (17/54) Oct 12 2021 Lot of people has implemented float to string conversion without
- IGotD- (9/11) Oct 12 2021 Floats to string is of course more complicated that integers but
- H. S. Teoh (8/22) Oct 12 2021 It'd be nice to untangle that ball of cables so that less cables get
- Hipreme (5/28) Oct 12 2021 I do hope that this gets noted by the decision people, having to
- H. S. Teoh (19/23) Oct 12 2021 On Tue, Oct 12, 2021 at 10:15:10PM +0000, Hipreme via Digitalmars-d wrot...
- Hipreme (7/29) Oct 13 2021 Humm I say module for representing libs, I have splitted my
- H. S. Teoh (13/21) Oct 13 2021 Hmm, I'd have thought LTO or -linkonce-templates ought to drop the
- Stefan Koch (6/26) Oct 12 2021 `writeln` itself even for plain strings is already quite heavy.
- Hipreme (5/38) Oct 12 2021 I'm not defending writeln (specially because in my code it causes
- russhy (13/33) Oct 12 2021 try to build with:
I have wrote a simple hello world using std.conv: ``` import std.conv:to; import std.stdio; export void MAIN(float b) { writeln("Hello World " ~ to!string(b)); } ``` Building that with dmd app.d -lib creates 500KB lib With `-g`, it goes up to 800KB Using ldc, the build time goes up by 2 times. if you simply change from `float b` to `int b`, the lib goes down from 500KB to 60KB. The build times decreases by almost 10x (must check), but I can feel that anyway. Using std.conv greatly degrades a modularized workflow, by increasing a lot of build time and binary size. I needed implementing my own to! function to get a much better build time for my program.
Oct 12 2021
On Tuesday, 12 October 2021 at 14:47:21 UTC, Hipreme wrote:Using std.conv greatly degrades a modularized workflow, by increasing a lot of build time and binary size. I needed implementing my own to! function to get a much better build time for my program.I've seen similar effects, not only with std.conv but with other modules as well. You just use a small part of one module but the compiler imports a lot of code. It would be very interesting to know what happens underneath and how we can reduce the code bloat. We should investigate what happens and we can use your example as case study.
Oct 12 2021
On Tuesday, 12 October 2021 at 14:47:21 UTC, Hipreme wrote:I have wrote a simple hello world using std.conv: ``` import std.conv:to; import std.stdio; export void MAIN(float b) { writeln("Hello World " ~ to!string(b)); } ``` Building that with dmd app.d -lib creates 500KB lib With `-g`, it goes up to 800KB Using ldc, the build time goes up by 2 times. if you simply change from `float b` to `int b`, the lib goes down from 500KB to 60KB.You compare apples and oranges. Convertion from integer types to string is trivial, converting float types to string is not. That being said there's some room for improvment. `writeln` of a `float` will take the same path as `format(%f, v)`, which contains the code to format float in every possible way, as the specifier is not known at compile time, and finally only a small part of the bloat generated is executed. This is bit strange, as for writeln, the specifier is known at compile time.The build times decreases by almost 10x (must check), but I can feel that anyway. Using std.conv greatly degrades a modularized workflow, by increasing a lot of build time and binary size. I needed implementing my own to! function to get a much better build time for my program.
Oct 12 2021
On Tuesday, 12 October 2021 at 16:04:49 UTC, user1234 wrote:On Tuesday, 12 October 2021 at 14:47:21 UTC, Hipreme wrote:Lot of people has implemented float to string conversion without requiring 500KB. I really don't think I need all that 'runtime speed' nor 'ultra precision', it would be great if we had some compiler flag to stop this template bloating thing for we can choose for build speed instead. Yea, writeln does cause 500KB requirement for `floats` and `struct`s too (without float members). I guess it is much more template hell than any other thing. Yea, I forced it for not inlining my number, because, that's the point, most of the time you won't be inlining a number. I have like, more than 8 modules, some depending on each other, this build time can increase a LOT linking time and the compile time. Usually, the modularized workflow should make things faster and reuse already compiled code. If the stdlib itself weights so much, the modularized workflow will start to feel uselessI have wrote a simple hello world using std.conv: ``` import std.conv:to; import std.stdio; export void MAIN(float b) { writeln("Hello World " ~ to!string(b)); } ``` Building that with dmd app.d -lib creates 500KB lib With `-g`, it goes up to 800KB Using ldc, the build time goes up by 2 times. if you simply change from `float b` to `int b`, the lib goes down from 500KB to 60KB.You compare apples and oranges. Convertion from integer types to string is trivial, converting float types to string is not. That being said there's some room for improvment. `writeln` of a `float` will take the same path as `format(%f, v)`, which contains the code to format float in every possible way, as the specifier is not known at compile time, and finally only a small part of the bloat generated is executed. This is bit strange, as for writeln, the specifier is known at compile time.The build times decreases by almost 10x (must check), but I can feel that anyway. Using std.conv greatly degrades a modularized workflow, by increasing a lot of build time and binary size. I needed implementing my own to! function to get a much better build time for my program.
Oct 12 2021
On Tuesday, 12 October 2021 at 18:06:53 UTC, Hipreme wrote:Lot of people has implemented float to string conversion without requiring 500KB.Floats to string is of course more complicated that integers but 500KB is ridiculous. It should rather be something like 10-20 KB. It's likely it is a combination of that the optimizer/linker is unable to remove unused functions. Also that imports usually imports more stuff, even if it is just a tiny function from another import. It's like a box of cables, you just want one cable but when you pull out one cable you get the entire ball of cables.
Oct 12 2021
On Tue, Oct 12, 2021 at 07:08:44PM +0000, IGotD- via Digitalmars-d wrote:On Tuesday, 12 October 2021 at 18:06:53 UTC, Hipreme wrote:It'd be nice to untangle that ball of cables so that less cables get pulled out when you tug at one (so to speak). :-D We talked about pay-as-you-go modularization of Phobos at least a few times, but so far, that ball of cables persist. T -- Never ascribe to malice that which is adequately explained by incompetence. -- Napoleon BonaparteLot of people has implemented float to string conversion without requiring 500KB.Floats to string is of course more complicated that integers but 500KB is ridiculous. It should rather be something like 10-20 KB. It's likely it is a combination of that the optimizer/linker is unable to remove unused functions. Also that imports usually imports more stuff, even if it is just a tiny function from another import. It's like a box of cables, you just want one cable but when you pull out one cable you get the entire ball of cables.
Oct 12 2021
On Tuesday, 12 October 2021 at 19:50:51 UTC, H. S. Teoh wrote:On Tue, Oct 12, 2021 at 07:08:44PM +0000, IGotD- via Digitalmars-d wrote:I do hope that this gets noted by the decision people, having to reimplement stdlib is the last thing I wanted right now, but 500KB for string to float conversion per module, (without debug symbols ) is pretty unacceptable.On Tuesday, 12 October 2021 at 18:06:53 UTC, Hipreme wrote:It'd be nice to untangle that ball of cables so that less cables get pulled out when you tug at one (so to speak). :-D We talked about pay-as-you-go modularization of Phobos at least a few times, but so far, that ball of cables persist. TLot of people has implemented float to string conversion without requiring 500KB.Floats to string is of course more complicated that integers but 500KB is ridiculous. It should rather be something like 10-20 KB. It's likely it is a combination of that the optimizer/linker is unable to remove unused functions. Also that imports usually imports more stuff, even if it is just a tiny function from another import. It's like a box of cables, you just want one cable but when you pull out one cable you get the entire ball of cables.
Oct 12 2021
On Tue, Oct 12, 2021 at 10:15:10PM +0000, Hipreme via Digitalmars-d wrote: [...] [...]I do hope that this gets noted by the decision people, having to reimplement stdlib is the last thing I wanted right now, but 500KB for string to float conversion per module, (without debug symbols ) is pretty unacceptable.[...] *Per module*?? That shouldn't be the case. You must be doing something wrong... Are you using dmd or ldc? You might want to look into various options for eliminating duplicate template instantiations, like -linkonce-templates, or LTO, or some such. No matter how bad the string-to-float bloat is (and I agree it's bad), it should not be adding bloat *per module*. Possibly one thing to watch out for is using compile-time format strings, i.e., `writeln!"abc %s def"(...)` instead of runtime format strings `writeln("abc %s def", ...)`. The former has its uses, such as catching bad format strings at compile-time; but it may potentially be the cause of a lot of template bloat if you have a lot of different format strings. T -- Being able to learn is a great learning; being able to unlearn is a greater learning.
Oct 12 2021
On Tuesday, 12 October 2021 at 22:58:51 UTC, H. S. Teoh wrote:On Tue, Oct 12, 2021 at 10:15:10PM +0000, Hipreme via Digitalmars-d wrote: [...] [...]Humm I say module for representing libs, I have splitted my project in various libs, whose I call modules, so, it needs to link to each lib I'm using. Although I have implemented most I need right now, the current problem is std.array. std.array increases 500Kb by only including it, so, for keeping my build times okay I have been basically ditching phobos...I do hope that this gets noted by the decision people, having to reimplement stdlib is the last thing I wanted right now, but 500KB for string to float conversion per module, (without debug symbols ) is pretty unacceptable.[...] *Per module*?? That shouldn't be the case. You must be doing something wrong... Are you using dmd or ldc? You might want to look into various options for eliminating duplicate template instantiations, like -linkonce-templates, or LTO, or some such. No matter how bad the string-to-float bloat is (and I agree it's bad), it should not be adding bloat *per module*. Possibly one thing to watch out for is using compile-time format strings, i.e., `writeln!"abc %s def"(...)` instead of runtime format strings `writeln("abc %s def", ...)`. The former has its uses, such as catching bad format strings at compile-time; but it may potentially be the cause of a lot of template bloat if you have a lot of different format strings. T
Oct 13 2021
On Thu, Oct 14, 2021 at 12:04:52AM +0000, Hipreme via Digitalmars-d wrote: [...]Humm I say module for representing libs, I have splitted my project in various libs, whose I call modules, so, it needs to link to each lib I'm using.Hmm, I'd have thought LTO or -linkonce-templates ought to drop the redundant templates once you link the libs. Is there any reason why it isn't?Although I have implemented most I need right now, the current problem is std.array. std.array increases 500Kb by only including it, so, for keeping my build times okay I have been basically ditching phobos...If I were you I'd report a bug. The mere act of importing std.array shouldn't pull in a whole bunch of dead weight if you don't even use anything. There used to be more Phobos modules with this problem, but a while back there was some effort to fix this. If std.array still has this problem it should get looked into. T -- Once the bikeshed is up for painting, the rainbow won't suffice. -- Andrei Alexandrescu
Oct 13 2021
On Tuesday, 12 October 2021 at 14:47:21 UTC, Hipreme wrote:I have wrote a simple hello world using std.conv: ``` import std.conv:to; import std.stdio; export void MAIN(float b) { writeln("Hello World " ~ to!string(b)); } ``` Building that with dmd app.d -lib creates 500KB lib With `-g`, it goes up to 800KB Using ldc, the build time goes up by 2 times. if you simply change from `float b` to `int b`, the lib goes down from 500KB to 60KB. The build times decreases by almost 10x (must check), but I can feel that anyway. Using std.conv greatly degrades a modularized workflow, by increasing a lot of build time and binary size. I needed implementing my own to! function to get a much better build time for my program.`writeln` itself even for plain strings is already quite heavy. I'd recommend using printf. I also have a realtively lightweight `dtoa` function. it's here: https://raw.githubusercontent.com/UplinkCoder/fpconv/master/src/fpconv_ctfe.d
Oct 12 2021
On Tuesday, 12 October 2021 at 16:05:19 UTC, Stefan Koch wrote:On Tuesday, 12 October 2021 at 14:47:21 UTC, Hipreme wrote:I'm not defending writeln (specially because in my code it causes 1500KB increase, but I could not reproduce in a simple hello world that increase), but the problem seems that std.conv for floats seems to consistently do thatI have wrote a simple hello world using std.conv: ``` import std.conv:to; import std.stdio; export void MAIN(float b) { writeln("Hello World " ~ to!string(b)); } ``` Building that with dmd app.d -lib creates 500KB lib With `-g`, it goes up to 800KB Using ldc, the build time goes up by 2 times. if you simply change from `float b` to `int b`, the lib goes down from 500KB to 60KB. The build times decreases by almost 10x (must check), but I can feel that anyway. Using std.conv greatly degrades a modularized workflow, by increasing a lot of build time and binary size. I needed implementing my own to! function to get a much better build time for my program.`writeln` itself even for plain strings is already quite heavy. I'd recommend using printf. I also have a realtively lightweight `dtoa` function. it's here: https://raw.githubusercontent.com/UplinkCoder/fpconv/master/src/fpconv_ctfe.d
Oct 12 2021
On Tuesday, 12 October 2021 at 14:47:21 UTC, Hipreme wrote:I have wrote a simple hello world using std.conv: ``` import std.conv:to; import std.stdio; export void MAIN(float b) { writeln("Hello World " ~ to!string(b)); } ``` Building that with dmd app.d -lib creates 500KB lib With `-g`, it goes up to 800KB Using ldc, the build time goes up by 2 times. if you simply change from `float b` to `int b`, the lib goes down from 500KB to 60KB. The build times decreases by almost 10x (must check), but I can feel that anyway. Using std.conv greatly degrades a modularized workflow, by increasing a lot of build time and binary size. I needed implementing my own to! function to get a much better build time for my program.try to build with: ```json "dflags-ldc": [ "-linkonce-templates", ], ``` i'd personally suggest using snprintf, but depending on your usecase that might not be perfect ```d char[32] tmp = 0; snprintf(tmp.ptr, tmp.length, "Hello World %f", value); ```
Oct 12 2021
On Tuesday, 12 October 2021 at 17:35:31 UTC, russhy wrote:On Tuesday, 12 October 2021 at 14:47:21 UTC, Hipreme wrote:snprintf can't be called at compile time, so, it can miss a lot. That flag didn't seem to do somethingI have wrote a simple hello world using std.conv: ``` import std.conv:to; import std.stdio; export void MAIN(float b) { writeln("Hello World " ~ to!string(b)); } ``` Building that with dmd app.d -lib creates 500KB lib With `-g`, it goes up to 800KB Using ldc, the build time goes up by 2 times. if you simply change from `float b` to `int b`, the lib goes down from 500KB to 60KB. The build times decreases by almost 10x (must check), but I can feel that anyway. Using std.conv greatly degrades a modularized workflow, by increasing a lot of build time and binary size. I needed implementing my own to! function to get a much better build time for my program.try to build with: ```json "dflags-ldc": [ "-linkonce-templates", ], ``` i'd personally suggest using snprintf, but depending on your usecase that might not be perfect ```d char[32] tmp = 0; snprintf(tmp.ptr, tmp.length, "Hello World %f", value); ```
Oct 12 2021
On Tuesday, 12 October 2021 at 17:35:31 UTC, russhy wrote:i'd personally suggest using snprintf, but depending on your usecase that might not be perfect ```d char[32] tmp = 0; snprintf(tmp.ptr, tmp.length, "Hello World %f", value); ```Be aware of [the bug with `snprintf`](https://issues.dlang.org/show_bug.cgi?id=22266) when compiling for Windows.
Oct 14 2021