digitalmars.D.learn - ranges
- Ellery Newcomer (29/29) Apr 29 2010 Hello.
- Ellery Newcomer (5/34) Apr 29 2010 Oh I get it. hasLength is broken.
- bearophile (4/7) Apr 29 2010 No need to write another bug report then.
- bearophile (40/44) Apr 29 2010 Some of the code written by Andrei can be bad. I have modified your code...
Hello. I'm muddling over the following code, which compares an array/take composition with the analogous imperative code. For medium-large values of n, I'm seeing a fivefold degradation in performance, which blows up to 30 times worse at n=50000000. Any ideas on why this is or better ways to accomplish the same? import std.range; import std.date; import std.random; import std.array; import std.stdio; void main(){ for(int n = 500; n <= 500000000; n *= 10){ writeln(n); auto r = rndGen(); auto tz = getUTCtime(); auto a = new int[n]; foreach(ref aa; a){ aa = r.front(); r.popFront(); } auto tz2 = getUTCtime(); auto a2 = array(take(r,n)); auto tz3 = getUTCtime(); writeln("\tarr: ",tz2-tz); writeln("\trange: ",tz3-tz2); } } ~
Apr 29 2010
Oh I get it. hasLength is broken. http://d.puremagic.com/issues/show_bug.cgi?id=3508 Kyle Foley's patch brings my program to a more respectable 1.6 times slower or thereabouts. On 04/29/2010 01:52 PM, Ellery Newcomer wrote:Hello. I'm muddling over the following code, which compares an array/take composition with the analogous imperative code. For medium-large values of n, I'm seeing a fivefold degradation in performance, which blows up to 30 times worse at n=50000000. Any ideas on why this is or better ways to accomplish the same? import std.range; import std.date; import std.random; import std.array; import std.stdio; void main(){ for(int n = 500; n <= 500000000; n *= 10){ writeln(n); auto r = rndGen(); auto tz = getUTCtime(); auto a = new int[n]; foreach(ref aa; a){ aa = r.front(); r.popFront(); } auto tz2 = getUTCtime(); auto a2 = array(take(r,n)); auto tz3 = getUTCtime(); writeln("\tarr: ",tz2-tz); writeln("\trange: ",tz3-tz2); } } ~
Apr 29 2010
Ellery Newcomer:http://d.puremagic.com/issues/show_bug.cgi?id=3508 Kyle Foley's patch brings my program to a more respectable 1.6 times slower or thereabouts.No need to write another bug report then. Bye, bearophile
Apr 29 2010
Ellery Newcomer:I'm muddling over the following code, which compares an array/take composition with the analogous imperative code. For medium-large values of n, I'm seeing a fivefold degradation in performance, which blows up to 30 times worse at n=50000000.Some of the code written by Andrei can be bad. I have modified your code like this: import std.range: front, popFront, array, take; import std.date: getUTCtime; import std.random: rndGen; import std.stdio: writeln; void main() { for (int n = 500; n <= 500_000_000; n *= 10) { writeln(n, ":"); auto rnd = rndGen(); auto t0 = getUTCtime(); auto rnd_arr1 = new int[n]; foreach (ref el; rnd_arr1) { el = rnd.front(); rnd.popFront(); } auto t1 = getUTCtime(); auto rnd_arr2 = new int[n]; int i; foreach (r; take(rnd, n)) rnd_arr2[i++] = r; auto t2 = getUTCtime(); auto rnd_arr3 = array(take(rnd, n)); auto t3 = getUTCtime(); writeln(" arr: ", t1 - t0); writeln(" take: ", t2 - t1); writeln(" range: ", t3 - t2); } } It shows that most of the time is spent by array(). After some experiments I have found that the Appender() is very slow. But the direct cause of this problem, beside the slowness of Appender() is that the hasLength is buggy and doesn't find the length of the take, using the Appender. If you replace the hasLenght with the equivalent from my dlibs1: template hasLength(R) { enum bool hasLength = is(typeof(R.length)) || is(typeof(R.init.length)) && !isNarrowString!R; } The problem essentially vanishes. The root of the problem is that Phobos has not enough unittests and it not battle-tested yet. I will probably write a bug report. Bye, bearophile
Apr 29 2010