performance #4

Open
opened 2021-06-04 17:58:47 +00:00 by benibela · 2 comments
benibela commented 2021-06-04 17:58:47 +00:00 (Migrated from github.com)

So it is usually faster than StrToFloat, but often slower than the traditional Val:



input: 123
val: 56 ns
strtofloat: 157 ns
bero: 76 ns


input: 12345678
val: 74 ns
strtofloat: 176 ns
bero: 86 ns


input: 123456789012345
val: 95 ns
strtofloat: 227 ns
bero: 97 ns


input: 1234567890123456789
val: 113 ns
strtofloat: 253 ns
bero: 104 ns


input: 123456781234567812345678
val: 153 ns
strtofloat: 285 ns
bero: 30997 ns


input: 1.2345e100
val: 105 ns
strtofloat: 241 ns
bero: 93 ns


input: 0.0000000012345678
val: 103 ns
strtofloat: 250 ns
bero: 117 ns


input: -1.234e-100
val: 106 ns
strtofloat: 241 ns
bero: 102 ns

{$mode objfpc}{$H+}

uses  Classes, PasDblStrUtils,math,bbdebugtools,sysutils
  { you can add units after this };

const FLT: array of string = ('123', '12345678', '123456789012345', '1234567890123456789',  '123456781234567812345678','1.2345e100', '0.0000000012345678', '-1.234e-100');
var s: string;
    d: double;
    i, ca: Integer;
    time: Cardinal;
begin
  for ca := low(FLT) to high(FLT) do begin
    s := FLT[ca];
    writeln;
    writeln;
    writeln('input: ',s);
    logging := true;
    time := GetTickCount;
    for i := 1 to 10000000 do
      val(s, d);
    time := GetTickCount - time;
    writeln('val: ', time div 10, ' ns');

    time := GetTickCount;
    for i := 1 to 10000000 do
      d := strtofloat(s);
    time := GetTickCount - time;
    writeln('strtofloat: ', time div 10, ' ns');

    time := GetTickCount;
    for i := 1 to 10000000 do
      d := ConvertStringToDouble(s);
    time := GetTickCount - time;
    writeln('bero: ', time div 10, ' ns');
  end;

end.

You could implement Eisel-Lemire to make it faster on the short numbers.

Although the longer numbers are actually probematic with 123456781234567812345678 where it is 200-times slower than Val

So it is usually faster than `StrToFloat`, but often slower than the traditional `Val`: ``` input: 123 val: 56 ns strtofloat: 157 ns bero: 76 ns input: 12345678 val: 74 ns strtofloat: 176 ns bero: 86 ns input: 123456789012345 val: 95 ns strtofloat: 227 ns bero: 97 ns input: 1234567890123456789 val: 113 ns strtofloat: 253 ns bero: 104 ns input: 123456781234567812345678 val: 153 ns strtofloat: 285 ns bero: 30997 ns input: 1.2345e100 val: 105 ns strtofloat: 241 ns bero: 93 ns input: 0.0000000012345678 val: 103 ns strtofloat: 250 ns bero: 117 ns input: -1.234e-100 val: 106 ns strtofloat: 241 ns bero: 102 ns ``` ```program Project1; {$mode objfpc}{$H+} uses Classes, PasDblStrUtils,math,bbdebugtools,sysutils { you can add units after this }; const FLT: array of string = ('123', '12345678', '123456789012345', '1234567890123456789', '123456781234567812345678','1.2345e100', '0.0000000012345678', '-1.234e-100'); var s: string; d: double; i, ca: Integer; time: Cardinal; begin for ca := low(FLT) to high(FLT) do begin s := FLT[ca]; writeln; writeln; writeln('input: ',s); logging := true; time := GetTickCount; for i := 1 to 10000000 do val(s, d); time := GetTickCount - time; writeln('val: ', time div 10, ' ns'); time := GetTickCount; for i := 1 to 10000000 do d := strtofloat(s); time := GetTickCount - time; writeln('strtofloat: ', time div 10, ' ns'); time := GetTickCount; for i := 1 to 10000000 do d := ConvertStringToDouble(s); time := GetTickCount - time; writeln('bero: ', time div 10, ' ns'); end; end. ``` You could implement Eisel-Lemire to make it faster on the short numbers. Although the longer numbers are actually probematic with `123456781234567812345678` where it is 200-times slower than Val
BeRo1985 commented 2021-06-04 22:47:54 +00:00 (Migrated from github.com)

So, EiselLemireStringToDouble is implemented now.

So, EiselLemireStringToDouble is implemented now.
benibela commented 2021-06-07 20:46:06 +00:00 (Migrated from github.com)

Great. The fast path is twice as fast as Val

Although algorithm M is rather slow, almost 50 times slower than Val



input: 123
val: 56 ns
strtofloat: 163 ns
bero: 25 ns


input: 12345678
val: 71 ns
strtofloat: 180 ns
bero: 35 ns


input: 123456789012345
val: 103 ns
strtofloat: 230 ns
bero: 53 ns


input: 1234567890123456789
val: 105 ns
strtofloat: 241 ns
bero: 4386 ns


input: 123456781234567812345678
val: 128 ns
strtofloat: 276 ns
bero: 5108 ns


input: 1.2345e100
val: 88 ns
strtofloat: 215 ns
bero: 46 ns


input: 0.0000000012345678
val: 102 ns
strtofloat: 227 ns
bero: 60 ns


input: -1.234e-100
val: 91 ns
strtofloat: 209 ns
bero: 42 ns

grafik

grafik

Great. The fast path is twice as fast as Val Although algorithm M is rather slow, almost 50 times slower than Val ``` input: 123 val: 56 ns strtofloat: 163 ns bero: 25 ns input: 12345678 val: 71 ns strtofloat: 180 ns bero: 35 ns input: 123456789012345 val: 103 ns strtofloat: 230 ns bero: 53 ns input: 1234567890123456789 val: 105 ns strtofloat: 241 ns bero: 4386 ns input: 123456781234567812345678 val: 128 ns strtofloat: 276 ns bero: 5108 ns input: 1.2345e100 val: 88 ns strtofloat: 215 ns bero: 46 ns input: 0.0000000012345678 val: 102 ns strtofloat: 227 ns bero: 60 ns input: -1.234e-100 val: 91 ns strtofloat: 209 ns bero: 42 ns ``` ![grafik](https://user-images.githubusercontent.com/1205129/121085359-09730000-c7e2-11eb-93f3-8caa50f57a2d.png) ![grafik](https://user-images.githubusercontent.com/1205129/121085404-1a237600-c7e2-11eb-9106-7dd5eec561c7.png)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
BeRo1985/pasdblstrutils#4
No description provided.