www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Reading array of integers readln performance issues

reply "kerdemdemir" <kerdemdemir hotmail.com> writes:
Hi;

To learn D better and challanging myself I am tring code 
computation's with D.

There is a question which is about reading a line of integer 
which consist of 200000 elements.

My solution fails because "Time limit exceeded", I thought it is 
because of my algorithm first. I realize time limit is exceeded 
even before my algorithm starts while reading line of integers. I 
understand this by giving a wrong answer to question after readln 
statement. I did that to get a "wrong answer error" but my code 
still get a "Time limit exceed" error because "readln" takes very 
long time.

Can I achieve something faster than code below?

auto peopleMoney = stdin.readln().split().map!(a => 
to!int(a)).array();
if (peopleMoney.length == 200000)
	 writeln(":(");

Regards
Erdem


Ps: I do not want to bore you with long code, but I am sending 
link to whole program anyway if anyone need.
  http://codeforces.com/contest/549/submission/11537206
Jun 11 2015
next sibling parent "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
On Thursday, 11 June 2015 at 19:56:00 UTC, kerdemdemir wrote:
 Hi;

 To learn D better and challanging myself I am tring code 
 computation's with D.

 There is a question which is about reading a line of integer 
 which consist of 200000 elements.

 My solution fails because "Time limit exceeded", I thought it 
 is because of my algorithm first. I realize time limit is 
 exceeded even before my algorithm starts while reading line of 
 integers. I understand this by giving a wrong answer to 
 question after readln statement. I did that to get a "wrong 
 answer error" but my code still get a "Time limit exceed" error 
 because "readln" takes very long time.

 Can I achieve something faster than code below?

 auto peopleMoney = stdin.readln().split().map!(a => 
 to!int(a)).array();
 if (peopleMoney.length == 200000)
 	 writeln(":(");

 Regards
 Erdem


 Ps: I do not want to bore you with long code, but I am sending 
 link to whole program anyway if anyone need.
  http://codeforces.com/contest/549/submission/11537206
Your algorithm works for about quadratic time. For N = 200000 your algorithm will work terribly long. The function `readln()` nothing to do with: http://codeforces.com/contest/549/submission/11476513 A faster way of `scanf`, but it will not help you, because your algorithm is slow.
Jun 11 2015
prev sibling parent reply "anonymous" <anonymous example.com> writes:
On Thursday, 11 June 2015 at 19:56:00 UTC, kerdemdemir wrote:
 Can I achieve something faster than code below?

 auto peopleMoney = stdin.readln().split().map!(a => 
 to!int(a)).array();
 if (peopleMoney.length == 200000)
 	 writeln(":(");
`std.array.split` is eager. It may be faster if you use the lazy `std.algorithm.splitter`: auto peopleMoney = stdin.readln().splitter().map!(to!int).array(); [...]
 Ps: I do not want to bore you with long code, but I am sending 
 link to whole program anyway if anyone need.
  http://codeforces.com/contest/549/submission/11537206
Seeing that you get the number of elements beforehand, you can preallocate the array, avoiding relocations of the data as elements are appended: peopleMoney = new int[peopleCount]; copy(stdin.readln().splitter().map!(to!int), peopleMoney); But these are tweaks. They may improve performance a little, but it won't be drastic. And anyway, I find it hard to believe that the original version takes more than a second to parse the input. Maybe try returning from the function in addition to printing ":(". Otherwise the program goes on, and the site may not show the output if the program as a whole took too long.
Jun 11 2015
parent "kerdemdemir" <kerdemdemir hotmail.com> writes:
Thanks a lot for your great advices and exaamples. Yes if I don't 
return; web-site won't show it as "wrong answer".

As a learner I am very happy with the responsiveness of the 
community.

Regards
Jun 12 2015