December 22, 2015
V Tue, 22 Dec 2015 18:11:24 +0000
rumbu via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
napsáno:

> 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!
> 
> Converting numbers to string involves the most expensive known two operations : division and modulus by 10.

No, IIRC few months or maybe years I have optimize this so it does not use division and modulus


December 22, 2015
V Tue, 22 Dec 2015 18:39:16 +0000
Ivan Kazmenko via Digitalmars-d-learn
<digitalmars-d-learn@puremagic.com> napsáno:

> On Tuesday, 22 December 2015 at 18:11:24 UTC, rumbu 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!
> >
> > Converting numbers to string involves the most expensive known two operations : division and modulus by 10.
> 
> When the base is known in advance, division and modulus can be substituted by a few additions, subtractions and bit shifts.  For example, the Hacker's Delight book has a chapter dedicated to that, as well as a freely available additional chapter (www.hackersdelight.org/divcMore.pdf).
> 
> 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


December 22, 2015
V Tue, 22 Dec 2015 17:15:27 +0000
Andrew Chapman via Digitalmars-d-learn
<digitalmars-d-learn@puremagic.com> napsáno:

> 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!
> 
> 

This is OK and expected :).

December 22, 2015
V Tue, 22 Dec 2015 09:43:00 -0800
"H. S. Teoh via Digitalmars-d-learn"
<digitalmars-d-learn@puremagic.com> napsáno:

> On Tue, Dec 22, 2015 at 05:23:11PM +0000, Andrew Chapman via Digitalmars-d-learn wrote: [...]
> >         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.
> [...]
> 
> I wonder if the slowdown is caused by GC collection cycles (because calling to!string will allocate, and here you're making a very large number of small allocations, which is known to cause GC performance issues).
> 
> Try inserting this before the loop:
> 
> 	import core.memory;
> 	GC.disable();
> 
> Does this make a difference in the running time?
> 
> 
> T
> 
This would  not help. It would probably be worse.

December 22, 2015
On Tuesday, 22 December 2015 at 19:45:46 UTC, Daniel Kozák wrote:
> V Tue, 22 Dec 2015 18:11:24 +0000
> rumbu via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> napsáno:
>
>> 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!
>> 
>> Converting numbers to string involves the most expensive known two operations : division and modulus by 10.
>
> No, IIRC few months or maybe years I have optimize this so it does not use division and modulus

It's using division and modulus, as expected:

https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L5529

If the compiler is smart enough, maybe it will replace this by well known multiplication trick.
December 22, 2015
On Tue, Dec 22, 2015 at 08:54:35PM +0100, Daniel Kozák via Digitalmars-d-learn wrote:
> V Tue, 22 Dec 2015 09:43:00 -0800
> "H. S. Teoh via Digitalmars-d-learn"
> <digitalmars-d-learn@puremagic.com> napsáno:
> 
> > On Tue, Dec 22, 2015 at 05:23:11PM +0000, Andrew Chapman via Digitalmars-d-learn wrote: [...]
> > >         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.
> > [...]
> > 
> > I wonder if the slowdown is caused by GC collection cycles (because calling to!string will allocate, and here you're making a very large number of small allocations, which is known to cause GC performance issues).
> > 
> > Try inserting this before the loop:
> > 
> > 	import core.memory;
> > 	GC.disable();
> > 
> > Does this make a difference in the running time?
> > 
> > 
> > T
> > 
> This would  not help. It would probably be worse.

I was not suggesting this as a solution, it's merely a way to determine whether the performance issue is GC-related.


T

-- 
"Hi." "'Lo."
December 22, 2015
On Tuesday, 22 December 2015 at 20:52:07 UTC, rumbu wrote:
> On Tuesday, 22 December 2015 at 19:45:46 UTC, Daniel Kozák wrote:
>> V Tue, 22 Dec 2015 18:11:24 +0000
>> rumbu via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
>> napsáno:
>>
>>> 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!
>>> 
>>> Converting numbers to string involves the most expensive known two operations : division and modulus by 10.
>>
>> No, IIRC few months or maybe years I have optimize this so it does not use division and modulus
>
> It's using division and modulus, as expected:
>
> https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L5529
>
> If the compiler is smart enough, maybe it will replace this by well known multiplication trick.

Tested it, I was right:

No optimizations: two divisions, one for the modulus and one for the division itself
Optimized: multiplication by 0xCCCCCCCD trick.

http://imgur.com/a/lHeHe




December 22, 2015
V Tue, 22 Dec 2015 20:52:07 +0000
rumbu via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
napsáno:

> On Tuesday, 22 December 2015 at 19:45:46 UTC, Daniel Kozák wrote:
> > V Tue, 22 Dec 2015 18:11:24 +0000
> > rumbu via Digitalmars-d-learn
> > <digitalmars-d-learn@puremagic.com>
> > napsáno:
> > 
> >> 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!
> >> 
> >> Converting numbers to string involves the most expensive known two operations : division and modulus by 10.
> >
> > No, IIRC few months or maybe years I have optimize this so it does not use division and modulus
> 
> It's using division and modulus, as expected:
> 
> https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L5529
> 
> If the compiler is smart enough, maybe it will replace this by well known multiplication trick.

Yes compiler is smart enought so it will not use division and modulus as I say before :)

December 22, 2015
V Tue, 22 Dec 2015 21:10:54 +0000
rumbu via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
napsáno:

> On Tuesday, 22 December 2015 at 20:52:07 UTC, rumbu wrote:
> > On Tuesday, 22 December 2015 at 19:45:46 UTC, Daniel Kozák wrote:
> >> V Tue, 22 Dec 2015 18:11:24 +0000
> >> rumbu via Digitalmars-d-learn
> >> <digitalmars-d-learn@puremagic.com>
> >> napsáno:
> >> 
> >>> 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!
> >>> 
> >>> Converting numbers to string involves the most expensive known two operations : division and modulus by 10.
> >>
> >> No, IIRC few months or maybe years I have optimize this so it does not use division and modulus
> >
> > It's using division and modulus, as expected:
> >
> > https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L5529
> >
> > If the compiler is smart enough, maybe it will replace this by well known multiplication trick.
> 
> Tested it, I was right:
> 
> No optimizations: two divisions, one for the modulus and one for
> the division itself
> Optimized: multiplication by 0xCCCCCCCD trick.
> 
> http://imgur.com/a/lHeHe
> 
> 

Yes this is expected :).

December 22, 2015
V Tue, 22 Dec 2015 12:55:10 -0800
"H. S. Teoh via Digitalmars-d-learn"
<digitalmars-d-learn@puremagic.com> napsáno:

> On Tue, Dec 22, 2015 at 08:54:35PM +0100, Daniel Kozák via Digitalmars-d-learn wrote:
> > V Tue, 22 Dec 2015 09:43:00 -0800
> > "H. S. Teoh via Digitalmars-d-learn"
> > <digitalmars-d-learn@puremagic.com> napsáno:
> > 
> > > On Tue, Dec 22, 2015 at 05:23:11PM +0000, Andrew Chapman via Digitalmars-d-learn wrote: [...]
> > > >         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.
> > > [...]
> > > 
> > > I wonder if the slowdown is caused by GC collection cycles (because calling to!string will allocate, and here you're making a very large number of small allocations, which is known to cause GC performance issues).
> > > 
> > > Try inserting this before the loop:
> > > 
> > > 	import core.memory;
> > > 	GC.disable();
> > > 
> > > Does this make a difference in the running time?
> > > 
> > > 
> > > T
> > > 
> > This would  not help. It would probably be worse.
> 
> I was not suggesting this as a solution, it's merely a way to determine whether the performance issue is GC-related.
> 
> 
> T
> 

Ok :)