December 22, 2015 Re: Most performant way of converting int to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to cym13 | On Tuesday, 22 December 2015 at 18:27:12 UTC, cym13 wrote:
> ...
> I don't think there is anything in the standard
> library that would really help here as (if I read it correctly) it is mainly
> because of the conversion from ranges to arrays that this code is slow.
Yes, it has been faster in past, when I last check and optimeze to!string. But because of @nogc it has been rewriten to Range base version which is slower. In this case it makes sense to add special version without @nogc (to!string will allocate memory anyway) which just use dup on buffer instead of make Range.
I will probably make pull request tomorrow.
|
December 22, 2015 Re: Most performant way of converting int to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Chapman | On 12/22/2015 10:15 AM, Andrew Chapman wrote: > On Tuesday, 22 December 2015 at 18:11:24 UTC, rumbu wrote: >> Converting numbers to string involves the most expensive known two >> operations : division and modulus by 10. > > Cool thanks, so essentially it's unavoidable There is hope. :) > I have a background in PHP programming where we don't really get exposed to > memory allocation, conversions etc. You will love Andrei's recently-released presentations from code::dive in November 2015: Writing Fast Code I: https://www.youtube.com/watch?v=ph7FP0LnmcA Writing Fast Code II: https://www.youtube.com/watch?v=3_FXy3cT5C8 Three Cool Things about D: https://youtube.com/watch?v=FdpaBHyQNco The first one has an example of optimizing uint64ToAscii() at around 1:16:30: https://www.youtube.com/watch?feature=player_detailpage&v=ph7FP0LnmcA#t=4604 Ali |
December 23, 2015 Re: Most performant way of converting int to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Chapman | On Tuesday, 22 December 2015 at 17:23:11 UTC, Andrew Chapman wrote:
> On Tuesday, 22 December 2015 at 17:18:16 UTC, cym13 wrote:
>> On Tuesday, 22 December 2015 at 17:15:27 UTC, Andrew Chapman wrote:
>>> Sorry if this is a silly question but is the to! method from the conv library the most efficient way of converting an integer value to a string?
>>>
>>> e.g.
>>> string s = to!string(100);
>>>
>>> I'm seeing a pretty dramatic slow down in my code when I use a conversion like this (when looped over 10 million iterations for benchmarking).
>>>
>>> Cheers!
>>
>> Out of curiosity a slow down compared to what? No conversion at all?
>
> Yeah, if I include a simple conversion in my loop:
>
> for({int i; i = 0;} i < num; i++) {
> //string s = to!string(i);
> Customer c = Customer(i, "Customer", "99998888", i * 2);
> string result = objS.serialize(c);
> }
>
> If I uncomment the "string s" line I'm seeing a 20% increase in running time, which given what's going on the rest of the code is quite surprising. I've tried compiling with both dmd and ldc2 - it's the same under both.
>
> Cheers.
Dynamic memory allocation is expensive. If the string is short-lived, allocate it on the stack:
enum maxDigits = to!string(ulong.max).length;
foreach(i; 0 .. num) {
char[maxDigits] buffer = void;
auto c = Customer(sformat(buffer[], "%s", i));
string result = objS.serialize(c);
}
Note that this is unsafe if the string (sformat's return value) outlives the loop iteration, as this is `buffer`'s scope.
|
December 23, 2015 Re: Most performant way of converting int to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | On Wednesday, 23 December 2015 at 11:21:32 UTC, Jakob Ovrum wrote: > Dynamic memory allocation is expensive. If the string is short-lived, allocate it on the stack: See also std.conv.toChars[1] for stringifying lazily/on-demand. http://dlang.org/phobos/std_conv#toChars |
December 23, 2015 Re: Most performant way of converting int to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | On Wednesday, 23 December 2015 at 11:46:37 UTC, Jakob Ovrum wrote: > On Wednesday, 23 December 2015 at 11:21:32 UTC, Jakob Ovrum wrote: >> Dynamic memory allocation is expensive. If the string is short-lived, allocate it on the stack: > > See also std.conv.toChars[1] for stringifying lazily/on-demand. > > http://dlang.org/phobos/std_conv#toChars Thanks Jakob! I did try toChars but I couldn't quite figure out a syntax of calling it that the compiler was happy with. From memory I tried things along the lines of: string v = toChars!(16,char,LetterCase.lower)(i); to convert an integer to Hex for example, but the compiler wasn't happy with it. How would I convert an int to a string using this? Cheers. |
December 23, 2015 Re: Most performant way of converting int to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Chapman | On 12/23/2015 02:29 PM, Andrew Chapman wrote: > string v = toChars!(16,char,LetterCase.lower)(i); > > to convert an integer to Hex for example, but the compiler wasn't happy > with it. How would I convert an int to a string using this? I had to squint at the error message to understand that the 16 specialization for radix requires that the value is unsigned. The following works: import std.conv; import std.algorithm; void main() { assert(1234u // <-- unsigned .toChars!(16, char, LetterCase.lower) .equal("4d2")); } Ali |
December 24, 2015 Re: Most performant way of converting int to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Chapman | On Wednesday, 23 December 2015 at 22:29:31 UTC, Andrew Chapman wrote: > On Wednesday, 23 December 2015 at 11:46:37 UTC, Jakob Ovrum wrote: >> On Wednesday, 23 December 2015 at 11:21:32 UTC, Jakob Ovrum wrote: >>> Dynamic memory allocation is expensive. If the string is short-lived, allocate it on the stack: >> >> See also std.conv.toChars[1] for stringifying lazily/on-demand. >> >> http://dlang.org/phobos/std_conv#toChars > > Thanks Jakob! I did try toChars but I couldn't quite figure out a syntax of calling it that the compiler was happy with. From memory I tried things along the lines of: > > string v = toChars!(16,char,LetterCase.lower)(i); > > to convert an integer to Hex for example, but the compiler wasn't happy with it. How would I convert an int to a string using this? > > Cheers. I haven't tested it, but: `toChars` doesn't return a string -- that's the whole point :) It returns a range, so you have to call it something like: auto v = toChars!(16,char,LetterCase.lower)(i); |
December 24, 2015 Re: Most performant way of converting int to string | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozák | On Tuesday, 22 December 2015 at 19:50:28 UTC, Daniel Kozák wrote:
> V Tue, 22 Dec 2015 18:39:16 +0000
> Ivan Kazmenko via Digitalmars-d-learn
> <digitalmars-d-learn@puremagic.com> napsáno:
>> Does DMD, or Phobos function to!(string), do anything like that? The number of possible bases is not large anyway. I've heard major C/C++ compilers do that, but have not looked for a proof myself.
>
> Yes, IIRC, all D compilers should be able to change modulus and division to few additions, subtractions and bit shifts if base is known at compile time.
>
> And phobos use this: https://github.com/D-Programming-Language/phobos/pull/1452
So, in a few common cases (bases 10 and 2, 4, 8, 16), you convert a runtime argument into a compile-time argument for the implementation function, and there, division is optimized at compile time. Nice!
|
Copyright © 1999-2021 by the D Language Foundation