Recent

Author Topic: To optimize RTL, make function PCharToInt  (Read 31975 times)

PascalDragon

  • Hero Member
  • *****
  • Posts: 3319
  • Compiler Developer
Re: To optimize RTL, make function PCharToInt
« Reply #45 on: July 30, 2021, 09:13:34 am »
Now if local variables or result could be declared to be open arrays

No. Those would need to be allocated on the heap (especially the return value) and then you can just as well use a dynamic array.

Slices won't help here, because the relevant functions that Alextp mentioned (e.g. SameText or LowerCase) take a String and not an array of Char, thus there will be a copy of the string anyway.

Then perhaps we need new overloaded functions

No, we don't. This is also about maintainability. And adding functions for everything and the kitchen sink is not maintainable. Also the main types for strings in Object Pascal are the various String types and not arrays of Char.

Especially an open array version of Val

And what would such a Val do?

winni

  • Hero Member
  • *****
  • Posts: 2662
Re: To optimize RTL, make function PCharToInt
« Reply #46 on: July 30, 2021, 10:40:42 am »

No, we don't. This is also about maintainability. And adding functions for everything and the kitchen sink is not maintainable. Also the main types for strings in Object Pascal are the various String types and not arrays of Char.

Thanx to PascalDragon!

And for those who are eager to optimize the whole day and night:

Pascal is not the right choice.
Use Forth.
There you can optimize everything.
On speed. On size. On everything.

Winni

Bart

  • Hero Member
  • *****
  • Posts: 4415
    • Bart en Mariska's Webstek
Re: To optimize RTL, make function PCharToInt
« Reply #47 on: July 30, 2021, 02:59:37 pm »
Use Forth.

Didn't you mean: "use the forceO:-)

Bart

winni

  • Hero Member
  • *****
  • Posts: 2662
Re: To optimize RTL, make function PCharToInt
« Reply #48 on: July 30, 2021, 04:35:13 pm »
Hi!

No, have a look at

https://en.wikipedia.org/wiki/Forth_(programming_language)

Forth is its own OS like UCSD Pascal or Oberon.

Forth is used for example in Riad Airport  and the controling of some satellites.
The Bios of the PowerMac is written in Forth.

Winni

BeniBela

  • Hero Member
  • *****
  • Posts: 817
    • homepage
Re: To optimize RTL, make function PCharToInt
« Reply #49 on: July 30, 2021, 07:18:54 pm »
No. Those would need to be allocated on the heap (especially the return value) and then you can just as well use a dynamic array.

But the point is to avoid heap allocations and return a reference to the already existing array
 
The Trim function would be the best example for that

No, we don't. This is also about maintainability. And adding functions for everything and the kitchen sink is not maintainable. Also the main types for strings in Object Pascal are the various String types and not arrays of Char.

And open arrays of char is how you make thing maintainable.

Especially if there were an automatic conversion from string to char array.

For example, there is CompareText

Code: Pascal  [Select][+][-]
  1. function CompareText(const S1, S2: string): Integer; overload;
  2.  
  3. var
  4.   i, count, count1, count2: sizeint;
  5.   Chr1, Chr2: byte;
  6.   P1, P2: PChar;
  7. begin
  8.   Count1 := Length(S1);
  9.   Count2 := Length(S2);
  10.   if (Count1>Count2) then
  11.     Count := Count2
  12.   else
  13.     Count := Count1;
  14.   i := 0;
  15.   if count>0 then
  16.     begin
  17.       P1 := @S1[1];
  18.       P2 := @S2[1];
  19.       while i < Count do
  20.         begin
  21.           Chr1 := byte(p1^);
  22.           Chr2 := byte(p2^);
  23.           if Chr1 <> Chr2 then
  24.             begin
  25.               if Chr1 in [97..122] then
  26.                 dec(Chr1,32);
  27.               if Chr2 in [97..122] then
  28.                 dec(Chr2,32);
  29.               if Chr1 <> Chr2 then
  30.                 Break;
  31.             end;
  32.           Inc(P1); Inc(P2); Inc(I);
  33.         end;
  34.     end;
  35.   if i < Count then
  36.     result := Chr1-Chr2
  37.   else
  38.     // CAPSIZEINT is no-op if Sizeof(Sizeint)<=SizeOF(Integer)
  39.     result:=CAPSIZEINT(Count1-Count2);
  40. end;    
  41.  

ShortCompareText

Code: Pascal  [Select][+][-]
  1. function ShortCompareText(const S1, S2: shortstring): SizeInt;
  2. var
  3.   c1, c2: Byte;
  4.   i: SizeInt;
  5.   L1, L2, Count: SizeInt;
  6.   P1, P2: PChar;
  7. begin
  8.   L1 := Length(S1);
  9.   L2 := Length(S2);
  10.   if L1 > L2 then
  11.     Count := L2
  12.   else
  13.     Count := L1;
  14.   i := 0;
  15.   P1 := @S1[1];
  16.   P2 := @S2[1];
  17.   while i < count do
  18.   begin
  19.     c1 := byte(p1^);
  20.     c2 := byte(p2^);
  21.     if c1 <> c2 then
  22.     begin
  23.       if c1 in [97..122] then
  24.         Dec(c1, 32);
  25.       if c2 in [97..122] then
  26.         Dec(c2, 32);
  27.       if c1 <> c2 then
  28.         Break;
  29.     end;
  30.     Inc(P1); Inc(P2); Inc(I);
  31.   end;
  32.   if i < count then
  33.     ShortCompareText := c1 - c2
  34.   else
  35.     ShortCompareText := L1 - L2;
  36. end;        
  37.  

and ShortCompareText again:

Code: Pascal  [Select][+][-]
  1. {$define FPC_HAS_COMPARETEXT_SHORTSTR}
  2. function ShortCompareText(const S1, S2: shortstring): SizeInt;
  3. var
  4.   c1, c2: Byte;
  5.   i: Integer;
  6.   L1, L2, Count: SizeInt;
  7.   P1, P2: PChar;
  8. begin
  9.   L1 := Length(S1);
  10.   L2 := Length(S2);
  11.   if L1 > L2 then
  12.     Count := L2
  13.   else
  14.     Count := L1;
  15.   i := 0;
  16.   P1 := @ShortstringClass(@S1).fdata[0];
  17.   P2 := @ShortstringClass(@S2).fdata[0];
  18.   c1 := 0;
  19.   c2 := 0;
  20.   while i < count do
  21.   begin
  22.     c1 := byte(p1[i]);
  23.     c2 := byte(p2[i]);
  24.     if c1 <> c2 then
  25.     begin
  26.       if c1 in [97..122] then
  27.         Dec(c1, 32);
  28.       if c2 in [97..122] then
  29.         Dec(c2, 32);
  30.       if c1 <> c2 then
  31.         Break;
  32.     end;
  33.     Inc(I);
  34.   end;
  35.   if i < count then
  36.     ShortCompareText := c1 - c2
  37.   else
  38.     ShortCompareText := L1 - L2;
  39. end;            
  40.  

If you merge these two functions (or three functions if jvm even has open arrays) to a single function with open char arrays, you only have to maintain half (a third) as many functions.
 


The Val function is especially horrible. 15 Val functions on 64-bit and a lot more:

Code: Pascal  [Select][+][-]
  1. {$ifndef FPUNONE}
  2. Function fpc_Val_Real_ShortStr(const s : shortstring; out code : ValSInt): ValReal; compilerproc;
  3. {$endif}
  4. Function fpc_Val_SInt_ShortStr(DestSize: SizeInt; Const S: ShortString; out Code: ValSInt): ValSInt; compilerproc;
  5. Function fpc_Val_UInt_Shortstr(Const S: ShortString; out Code: ValSInt): ValUInt; compilerproc;
  6. function fpc_val_enum_shortstr(str2ordindex:pointer;const s:shortstring;out code:valsint):longint; compilerproc;
  7. Function fpc_Val_Currency_ShortStr(const s : shortstring; out Code : ValSInt): currency; compilerproc;
  8. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  9. {$ifndef FPUNONE}
  10. Function fpc_Val_Real_AnsiStr(Const S : RawByteString; out Code : ValSInt): ValReal; compilerproc;
  11. {$endif}
  12. Function fpc_Val_UInt_AnsiStr (Const S : RawByteString; out Code : ValSInt): ValUInt; compilerproc;
  13. Function fpc_Val_SInt_AnsiStr (DestSize: SizeInt; Const S : RawByteString; out Code : ValSInt): ValSInt; compilerproc;
  14. Function fpc_Val_Currency_AnsiStr(Const S : RawByteString; out Code : ValSInt): Currency; compilerproc;
  15. function fpc_Val_enum_ansistr(str2ordindex:pointer;const s:RawByteString;out code:valsint):longint; compilerproc;
  16. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  17.  
  18. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  19.   {$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  20.   {$ifndef FPUNONE}
  21.   Function fpc_Val_Real_WideStr(Const S : WideString; out Code : ValSInt): ValReal; compilerproc;
  22.   {$endif}
  23.   Function fpc_Val_SInt_WideStr (DestSize: SizeInt; Const S : WideString; out Code : ValSInt): ValSInt; compilerproc;
  24.   Function fpc_Val_UInt_WideStr (Const S : WideString; out Code : ValSInt): ValUInt; compilerproc;
  25.   function fpc_val_Enum_WideStr (str2ordindex:pointer;const s:WideString;out code:valsint):longint;compilerproc;
  26.   Function fpc_Val_Currency_WideStr(Const S : WideString; out Code : ValSInt): Currency; compilerproc;
  27.   {$endif ndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  28.   {$ifndef FPUNONE}
  29.   Function fpc_Val_Real_UnicodeStr(Const S : UnicodeString; out Code : ValSInt): ValReal; compilerproc;
  30.   {$endif}
  31.   Function fpc_Val_SInt_UnicodeStr (DestSize: SizeInt; Const S : UnicodeString; out Code : ValSInt): ValSInt; compilerproc;
  32.   Function fpc_Val_UInt_UnicodeStr (Const S : UnicodeString; out Code : ValSInt): ValUInt; compilerproc;
  33.   function fpc_val_Enum_UnicodeStr(str2ordindex:pointer;const s:UnicodeString;out code:valsint):longint;compilerproc;
  34.   Function fpc_Val_Currency_UnicodeStr(Const S : UnicodeString; out Code : ValSInt): Currency; compilerproc;
  35. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  36.  
  37. {$ifndef CPU64}
  38. Function fpc_val_int64_shortstr(Const S: ShortString; out Code: ValSInt): Int64; compilerproc;
  39. Function fpc_val_qword_shortstr(Const S: ShortString; out Code: ValSInt): QWord; compilerproc;
  40. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  41. Function fpc_Val_qword_AnsiStr (Const S : RawByteString; out Code : ValSInt): qword;compilerproc;
  42. Function fpc_Val_int64_AnsiStr (Const S : RawByteString; out Code : ValSInt): Int64; compilerproc;
  43. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  44.  
  45. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  46. {$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  47. Function fpc_Val_qword_WideStr (Const S : WideString; out Code : ValSInt): qword; compilerproc;
  48. Function fpc_Val_int64_WideStr (Const S : WideString; out Code : ValSInt): Int64; compilerproc;
  49. {$endif ndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  50. Function fpc_Val_qword_UnicodeStr (Const S : UnicodeString; out Code : ValSInt): qword; compilerproc;
  51. Function fpc_Val_int64_UnicodeStr (Const S : UnicodeString; out Code : ValSInt): Int64; compilerproc;
  52. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  53.  
  54. {$endif CPU64}
  55.  
  56. {$if defined(CPU16) or defined(CPU8)}
  57. Function fpc_val_longint_shortstr(Const S: ShortString; out Code: ValSInt): LongInt; compilerproc;
  58. Function fpc_val_longword_shortstr(Const S: ShortString; out Code: ValSInt): LongWord; compilerproc;
  59. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  60. Function fpc_Val_longword_AnsiStr (Const S : RawByteString; out Code : ValSInt): LongWord;compilerproc;
  61. Function fpc_Val_longint_AnsiStr (Const S : RawByteString; out Code : ValSInt): LongInt; compilerproc;
  62. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  63.  
  64. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  65. {$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  66. Function fpc_Val_longword_WideStr (Const S : WideString; out Code : ValSInt): LongWord; compilerproc;
  67. Function fpc_Val_longint_WideStr (Const S : WideString; out Code : ValSInt): LongInt; compilerproc;
  68. {$endif ndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  69. Function fpc_Val_longword_UnicodeStr (Const S : UnicodeString; out Code : ValSInt): LongWord; compilerproc;
  70. Function fpc_Val_longint_UnicodeStr (Const S : UnicodeString; out Code : ValSInt): LongInt; compilerproc;
  71. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  72.  
  73. Function fpc_val_smallint_shortstr(Const S: ShortString; out Code: ValSInt): SmallInt; compilerproc;
  74. Function fpc_val_word_shortstr(Const S: ShortString; out Code: ValSInt): Word; compilerproc;
  75. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  76. Function fpc_Val_word_AnsiStr (Const S : RawByteString; out Code : ValSInt): Word;compilerproc;
  77. Function fpc_Val_smallint_AnsiStr (Const S : RawByteString; out Code : ValSInt): SmallInt; compilerproc;
  78. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  79.  
  80. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  81. {$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  82. Function fpc_Val_word_WideStr (Const S : WideString; out Code : ValSInt): Word; compilerproc;
  83. Function fpc_Val_smallint_WideStr (Const S : WideString; out Code : ValSInt): SmallInt; compilerproc;
  84. {$endif ndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  85. Function fpc_Val_word_UnicodeStr (Const S : UnicodeString; out Code : ValSInt): Word; compilerproc;
  86. Function fpc_Val_smallint_UnicodeStr (Const S : UnicodeString; out Code : ValSInt): SmallInt; compilerproc;
  87. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  88. {$endif CPU16 or CPU8}
  89.  


That are 10 useless functions which could be completely removed by open array of char and implicit string conversion.

And what would such a Val do?

It should do what Val always does and convert the string to a number type


And be much faster because it would not convert it to a shortstring first


And it should actually work, because there are numbers that are too long to be converted to a shortstring. Right now Val is  broken for too many floating point numbers.


For example 1.000000000000000083440445735494114201498374684297748090773074248463985239407051498604593735845779837892931801205519006540143046983522050187320219603051931177873942083183212403692841435861457337958101109706529749626122129770312276153129073731249624318317970050884468946605920791625976563 E-100.


It is too long to be converted to a shortstring.

If you truncate it after 256 characters, and convert that to double, Val returns 1e-100. Which is just wrong, because the number is not 1e-100. It is closer to double(1.0000000000000001E-100) = 1.000000000000000146888991668385344783348988580061336761363545490991374779558559529591511183078266686203117527600126162281757823427294446352372003164142598747391601025087706864660753929253834010024571626412624920649942809289830052437699004074943449904555592411270481534302234649658203125 E-100





Pascal is not the right choice.
Use Forth.
There you can optimize everything.
On speed. On size. On everything.


I use Pascal, because it used to be especially fast

winni

  • Hero Member
  • *****
  • Posts: 2662
Re: To optimize RTL, make function PCharToInt
« Reply #50 on: July 30, 2021, 08:00:55 pm »
Hi!

From your university mind games back to reality:

A Double has a 15..16 significant decimal digits precision.

Whatever you put into a string[255]  - a double will not take all the information.

And that is because we all work with some kind of a PC.
And not with some super-duper-number-crunchers

Winni


BeniBela

  • Hero Member
  • *****
  • Posts: 817
    • homepage
Re: To optimize RTL, make function PCharToInt
« Reply #51 on: July 30, 2021, 08:27:20 pm »

A Double has a 15..16 significant decimal digits precision.


That is for printing a double

Parsing a string to a double needs to consider all digits: https://www.exploringbinary.com/decimal-to-floating-point-needs-arbitrary-precision/

winni

  • Hero Member
  • *****
  • Posts: 2662
Re: To optimize RTL, make function PCharToInt
« Reply #52 on: July 30, 2021, 08:43:47 pm »

A Double has a 15..16 significant decimal digits precision.


That is for printing a double

Parsing a string to a double needs to consider all digits: https://www.exploringbinary.com/decimal-to-floating-point-needs-arbitrary-precision/

Please read the links that you advise.

The Discussion goes: How many more BITS beyond bit 54 are needed, before you can decide if 54 is zero or one.

And how many bits you can put in a string255 with digits?????
Think about it.
Or compute. If you can.

Winni

« Last Edit: July 30, 2021, 09:19:41 pm by winni »

winni

  • Hero Member
  • *****
  • Posts: 2662
Re: To optimize RTL, make function PCharToInt
« Reply #53 on: July 30, 2021, 09:36:44 pm »
Hi!

200 digits in, only 15 digits precision out.
As we all knew before and the "wise fpc book" said.

Simple test:
Code: Pascal  [Select][+][-]
  1. const tenDigits = '9876543210';
  2. var s : string;
  3.     d: double;
  4.     i,err: Integer;
  5. begin
  6.    s := '';
  7.    for i := 1 to 20 do s := s +tenDigits;
  8.    val (s,d,err);
  9.    writeln  (d);
  10.   end;  
                   


This results in

Code: Text  [Select][+][-]
  1. 9.87654321098765E199
  2.  

needless to say

Winni

Bart

  • Hero Member
  • *****
  • Posts: 4415
    • Bart en Mariska's Webstek
Re: To optimize RTL, make function PCharToInt
« Reply #54 on: July 30, 2021, 10:49:08 pm »
No, have a look at

https://en.wikipedia.org/wiki/Forth_(programming_language)

I knew that.
It was an attempt at humor.
Obviously I failed.

Bart

winni

  • Hero Member
  • *****
  • Posts: 2662
Re: To optimize RTL, make function PCharToInt
« Reply #55 on: July 30, 2021, 11:21:00 pm »


I knew that.
It was an attempt at humor.
Obviously I failed.

Bart

Sorry. So it was me who failed.
Humor is so seldom in this forum (the same with women) so I don't exspect it.
And obvious overlooked it.

But some fun facts concerning Forth:

Forth was not only part of the Space Shuttle but it was the OS and programming language for the pinball machines. Since the time they had a chip and not only relais (click clack).

Winni (aka Pinball Wizard)
« Last Edit: July 30, 2021, 11:23:39 pm by winni »

440bx

  • Hero Member
  • *****
  • Posts: 2468
Re: To optimize RTL, make function PCharToInt
« Reply #56 on: July 31, 2021, 12:21:57 am »
Humor is so seldom in this forum (the same with women) so I don't exspect it.
Maybe it would "optimize" the forums to have a dating section... <chuckle>
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 2924
Re: To optimize RTL, make function PCharToInt
« Reply #57 on: July 31, 2021, 01:18:52 am »
Carbon dating?

Talking about Forth and  humor:
Quote
Forth is so-named, because in 1968 "the file holding the interpreter was labeled FOURTH, for 4th (next) generation software, but the IBM 1130 operating system restricted file names to five characters."

winni

  • Hero Member
  • *****
  • Posts: 2662
Re: To optimize RTL, make function PCharToInt
« Reply #58 on: July 31, 2021, 10:26:26 am »

Talking about Forth and  humor:
Quote
Forth is so-named, because in 1968 "the file holding the interpreter was labeled FOURTH, for 4th (next) generation software, but the IBM 1130 operating system restricted file names to five characters."

Hi!

That were the times when RAM and disk space was rare and expensive.

Another Example of those restrictions:
UCSD Pascal uses only the first 15 chars of a variable name.
If you made a typo beyond string[15] it never occured as error.
Until ....
Some years later you ported your program to Turbo.
There the first 63 chars of a variable were significant.

And another byte fiddeling use:
UCSD Pascal aligned a string to word borders (16 bit times)
So  it was a waste to declare a string[20] because it used 21 bytes and one byte was wasted.
So you always declared an odd string length that nothing was unused!

For the "young blood":
A  5 1/4 inch  floopy disk had (in the beginning) a capacity of 360 kB and an 8 inch floppy  1.1 MB

Glad that we dont have to fight this battle anymore.

Winni

ccrause

  • Sr. Member
  • ****
  • Posts: 434
Re: To optimize RTL, make function PCharToInt
« Reply #59 on: July 31, 2021, 10:39:00 am »
Carbon dating?
Because we use an ancient "dead" tongue?  :P

 

TinyPortal © 2005-2018