Recent

Author Topic: Too many cycles  (Read 9580 times)

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Too many cycles
« Reply #15 on: September 24, 2018, 01:01:07 am »
Why "RoundTo"? Doesn't the ":2" just do this? But this won't be very noticable...

I could imagine that a simple buffered stream could speed things up considerably: Write primarily to a memory stream, and after every, say, 100000 write operations copy the memory stream to the file stream. Then reset the memory stream for the next iteration.
« Last Edit: September 24, 2018, 01:18:06 am by wp »

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: Too many cycles
« Reply #16 on: September 24, 2018, 07:57:34 am »
Indeed. FWIW this seems close to the other solutions:
Code: Pascal  [Select][+][-]
  1. program untitled;
  2. {$mode delphi}
  3. uses
  4.   sysutils, classes, bufstream;
  5. var
  6.   i, j, k, count : Integer;
  7.   T0, T1, Diff: TDateTime;
  8.   SS,SB:TStream;
  9. begin
  10.   T0 := Now;
  11.   if FileExists('test.txt') then Deletefile('test.txt');
  12.   SS:=TFilestream.Create('test.txt', fmCreate or fmOpenWrite or fmShareExclusive);
  13.   SB:=TWriteBufStream.Create(SS,16384);
  14.   count := 0;
  15.   for i := 1 to   20 do
  16.   try
  17.     for j := 1 to 8765 do
  18.       if (j <> i) then
  19.         for k := 1 to 5673 do        
  20.           if (k <> i) and (k <> j) then
  21.           begin
  22.             Inc(count);
  23.             if ((Count mod 100000)=0) then writeln(count);
  24.             SB.WriteAnsiString(
  25.                     (i / 3).ToString(ffNumber,4,2)+' '+
  26.                     (j / 4).ToString(ffNumber,4,2)+' '+
  27.                     (k / 2).ToString(ffNumber,4,2));
  28.           end;        
  29.   finally
  30.     SB.Free;
  31.     SS.Free;
  32.   end;
  33.   T1 := Now;
  34.   Diff := T1-T0;
  35.   writeln(count,' items: ',timetostr(Diff));
  36. end.
Specialize a type, not a var.

bytebites

  • Hero Member
  • *****
  • Posts: 632
Re: Too many cycles
« Reply #17 on: September 24, 2018, 08:31:57 am »
Code: Pascal  [Select][+][-]
  1. program untitled;
  2.  
  3. {$mode delphi}
  4. uses
  5.   SysUtils,
  6.   Classes,
  7.   bufstream;
  8.  
  9. var
  10.   i, j, k, Count: integer;
  11.   T0, T1, Diff: TDateTime;
  12.   SS, SB: TStream;
  13.   si, sj: string;
  14. begin
  15.   T0 := Now;
  16.   if FileExists('test.txt') then
  17.     Deletefile('test.txt');
  18.   SS := TFilestream.Create('test.txt', fmCreate or fmOpenWrite or fmShareExclusive);
  19.   SB := TWriteBufStream.Create(SS, 16384);
  20.   Count := 0;
  21.   try
  22.     for i := 1 to 20 do
  23.     begin
  24.       si := (i / 3).ToString(ffNumber, 4, 2);
  25.       for j := 1 to 8765 do
  26.         if (j <> i) then
  27.         begin
  28.           sj := (j / 4).ToString(ffNumber, 4, 2);
  29.           for k := 1 to 5673 do
  30.             if (k <> i) and (k <> j) then
  31.             begin
  32.               Inc(Count);
  33.               if ((Count mod 100000) = 0) then
  34.                 writeln(Count);
  35.               SB.WriteAnsiString(
  36.                 si + ' ' + sj + ' ' +
  37.                 (k / 2).ToString(ffNumber, 4, 2));
  38.             end;
  39.         end;
  40.     end;
  41.   finally
  42.     SB.Free;
  43.     SS.Free;
  44.   end;
  45.   T1 := Now;
  46.   Diff := T1 - T0;
  47.   writeln(Count, ' items: ', timetostr(Diff));
  48. end.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: Too many cycles
« Reply #18 on: September 24, 2018, 08:54:15 am »
bytebites I think that's wrong: you format too much that way. Bringing counters outside of the loop is OK, but formatting is another story.
Format only if it is known there will be output. What you did is preformatting values that are never used, which is the opposite of efficient... :D
Specialize a type, not a var.

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Too many cycles
« Reply #19 on: September 24, 2018, 09:08:20 am »
No, he is not pre-formatting, but pre-calculating. Why should the value of i/3 be calculated and converted to string in the innermost k-loop 8675*5673 times when only the string value of i/3 is needed and can be calculated once in the outermost i-loop?

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: Too many cycles
« Reply #20 on: September 24, 2018, 09:13:03 am »
bytebites I think that's wrong: you format too much that way. Bringing counters outside of the loop is OK, but formatting is another story.
Format only if it is known there will be output. What you did is preformatting values that are never used, which is the opposite of efficient... :D
No. Read the code properly: he is preformatting (ToString). If the conditions for the innermost loop are not met he just wasted cycles...
« Last Edit: September 24, 2018, 09:29:21 am by Thaddy »
Specialize a type, not a var.

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Too many cycles
« Reply #21 on: September 24, 2018, 09:27:27 am »
But there are MUCH more cases when i/3 is calculated and formatted to string unnecessarily in the innermost loop of your code, than in the outermost loop of bytebite's code

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: Too many cycles
« Reply #22 on: September 24, 2018, 09:31:39 am »
But there are MUCH more cases when i/3 is calculated and formatted to string unnecessarily in the innermost loop of your code, than in the outermost loop of bytebite's code

There are actually NO cases where I use unnecessary formatting: only if all conditions are met the format routines are called.
Specialize a type, not a var.

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Too many cycles
« Reply #23 on: September 24, 2018, 09:58:56 am »
Let me explain my arguments with a simpler problem. In the following project which corresponds to your code, IntToStr(i/3) is calculated 900 times
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. var
  3.   i,j: Integer;
  4. begin
  5.   for i:=1 to 10 do
  6.     if i <> 5 then
  7.       for j := 100 do
  8.         WriteLn(IntToStr(i/3));
  9. end.
In the next project which corresponds to bytebite's code, IntToStr(i/3) is calculated only 10 times although one of them is not necessary - and even this could be avoided by putting it after the "IF", but you would not notice the difference compared to the 900 unnecessary calculations of your code.
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. var
  3.   i,j: Integer;
  4.   s: String;
  5. begin
  6.   for i:=1 to 10 do begin
  7.     s := IntToStr(i/3);
  8.     if i <> 5 then
  9.       for j:=1 to 100 do
  10.         WriteLn(s);
  11.   end;
  12. end.  

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: Too many cycles
« Reply #24 on: September 24, 2018, 10:07:04 am »
Yes. That's why I usually bring as much as I can  outside the loop.  I just didn't notice the huge amount of output in this case. You are right.
But it depends. Usually such code requires some attention: expense of formatting vs expense of loop times. In this case the output is many and not few.
Specialize a type, not a var.

BrunoK

  • Sr. Member
  • ****
  • Posts: 452
  • Retired programmer
Re: Too many cycles
« Reply #25 on: September 24, 2018, 11:05:01 am »
Additionaly in Thaddy's code it seems that :
Code: Pascal  [Select][+][-]
  1.   for i := 1 to 20 do
  2.     try
  3.       for j := 1 to 8765 do
  4.         if (j <> i) then
  5.           for k := 1 to 5673 do
  6.             if (k <> i) and (k <> j) then begin
  7.               Inc(Count);
  8.               if ((Count mod 100000) = 0) then
  9.                 writeln(Count);
  10.               SB.WriteAnsiString(
  11.                 (i / 3).ToString(ffNumber, 4, 2) + ' ' +
  12.                 (j / 4).ToString(ffNumber, 4, 2) + ' ' +
  13.                 (k / 2).ToString(ffNumber, 4, 2));
  14.             end;
  15.     finally
  16.       SB.Free;
  17.       SS.Free;
  18.     end;
  19.  
will free SB and SS after the first iteration of i. On the second iteration, if it works, SB and SS are not valid objects any more.
Was it tested ?

In any case it is difficult to understand what the original poster intentions are.

Bart

  • Hero Member
  • *****
  • Posts: 5274
    • Bart en Mariska's Webstek
Re: Too many cycles
« Reply #26 on: September 24, 2018, 10:44:47 pm »
Using Thaddy's approach with TBufStream and TFileStream makes the program 30% slower than the classic writeln(file,..) in combination with SetTextBuf().

Bart

damieiro

  • Full Member
  • ***
  • Posts: 200
Re: Too many cycles
« Reply #27 on: September 24, 2018, 11:08:24 pm »
I do not know what the poster wants, but if speed is needed i would precalculate the 20 i/3 strings, the 8765 j /4 strings and the 5673 k/2 strings (storing in their own arrays of strings) and then do the loops using indexes to the precalculated arrays in the inner loop calculus...

And sure are other loop optimizations... (transforming the for in while loops or only single big loop using conditions like if i=j then j:=j+1 and thinks like that instead of triple <>

« Last Edit: September 25, 2018, 03:37:00 pm by damieiro »

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Too many cycles
« Reply #28 on: September 25, 2018, 12:32:21 am »
Using Thaddy's approach with TBufStream and TFileStream makes the program 30% slower than the classic writeln(file,..) in combination with SetTextBuf().
Amazing!

guest58172

  • Guest
Re: Too many cycles
« Reply #29 on: September 25, 2018, 12:49:56 am »
OP feedback required at this point.

 

TinyPortal © 2005-2018