December 22, 2015
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
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
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
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
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
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
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
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!
1 2 3
Next ›   Last »