#1 Re: Other components » SynCommons.pas Int32ToUTF8 question » 2012-12-25 03:54:53

At lot of things to think about, thanks for the detailed reply!

#2 Re: Other components » SynCommons.pas Int32ToUTF8 question » 2012-12-20 07:24:17

Thank you but...

I'm actually using TopMemory, I can't use SynScaleMM (it crashed several times on my main project). As far as I can tell, OmniThreadLibrary & SynScaleMM hate each other.

The only time I got a better speed was when I used StringReplaceAll() & Int32ToUTF8(), otherwise replacement routines *with* string conversion made speed worst (string conversion is the one to blame, but since I'm interested in the end result...)

That's really too bad, SynCommons.pas really does contain some seriously fast stuff, people would greatly benefit from it if it was made general-purpose

FWIW, here's the code that I tried (TopMemory used):

// ------------------------------------------------------------------------------ //
procedure TForm1.Button1Click(Sender: TObject);
const
     TestString = '  (const S, OldPattern, NewPattern تلاوة : RawUTF8)  Test Data  ';
var
   Utf8    : RawUTF8;
   sText   : String;
   TheTime : Integer;
   i, k    : Integer;
begin
     // ------------------------------------------------------------- //
     // Test Trim
     TheTime   := GetTickCount();
     for i := 1 to 1000000 do
         sText := SysUtils.Trim(TestString);
     Memo1.Lines.Add('Classic Trim() timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds.' + sText);  // }

     TheTime   := GetTickCount();
     for i := 1 to 1000000 do
         sText := UTF8ToString(Trim(TestString));
     Memo1.Lines.Add('SynCommons Trim() timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds.' + sText);  // }
     Memo1.Lines.Add('------------');

     // ------------------------------------------------------------- //
     // Test Pos
     TheTime   := GetTickCount();
     for i := 1 to 1000000 do
         k     := System.Pos(' Da', TestString);
     Memo1.Lines.Add('Classic Pos() timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds.' + IntToStr(k));  // }

     TheTime   := GetTickCount();
     for i := 1 to 1000000 do
         k     := Pos(' Da', TestString);
     Memo1.Lines.Add('SynCommons Pos() timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds.' + IntToStr(k));  // }
     Memo1.Lines.Add('------------');

     // ------------------------------------------------------------- //
     // Test IntToStr
     TheTime   := GetTickCount();
     for i := 1 to 1000000 do
         sText := IntToStr(i);
     Memo1.Lines.Add('Classic IntToStr() timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds.' + sText);  // }

     TheTime   := GetTickCount();
     for i := 1 to 1000000 do
         sText := Ansi7ToString(Int32ToUTF8(i));
     Memo1.Lines.Add('SynCommons Int32ToUTF8() timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds.' + sText);  // }
     Memo1.Lines.Add('------------');

     // ------------------------------------------------------------- //
     // Test StringReplace
     TheTime   := GetTickCount();
     for i := 1 to 1000000 do
         sText := SysUtils.StringReplace('(const S, OldPattern, NewPattern: RawUTF8)  Test Data  ', 'Dat', 'NEW_DAT', [rfIgnoreCase, rfReplaceAll]);
     Memo1.Lines.Add('Classic StringReplace() timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds.' + sText);  // }

     TheTime   := GetTickCount();
     for i := 1 to 1000000 do
         sText := UTF8ToString(SynCommons.StringReplaceAll(TestString, 'Dat', 'NEW_DAT'));
     Memo1.Lines.Add('SynCommons StringReplace() timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds.' + sText);  // }
     Memo1.Lines.Add('------------');
     // ------------------------------------------------------------- //
end;
// ------------------------------------------------------------------------------ //

#3 Re: Other components » SynCommons.pas Int32ToUTF8 question » 2012-12-19 18:55:48

Thank you!

Given the fact that most delphi developers use String rather than RawUTF8, I wonder why you chose not to use string?

I highly suspect the use of RawUTF8 does prevent many (if not most) developers from using these fast routines, simply because (1) the string conversion make the speed gain a lot less significant and (2) it's a lot more difficult to use it in existing projects.

One obvious example is when I have to pass the result of, say, IntToStr to another component that expects String.

According to my tests, even when using the Ansi7ToString (I tried UTF8ToString() as well), overall speed gain (after string conversion) was marginal at best, and sometimes string conversion routine made things so bad that overall operation was actually *slower*

For these reasons, I think having direct string-based routines would be best (performance-wise).

Any chance we'll see something like this? smile

#4 Re: Other components » SynCommons.pas Int32ToUTF8 question » 2012-12-19 07:16:26

OK, I changed the test code to this:

// --------------------------------------------------------------- //
var
   Utf8    : RawUTF8;
   TheTime : Integer;
   i       : Integer;
begin
     TheTime   := GetTickCount();
     for i := 1 to 10000000 do
         Utf8  := Int32ToUTF8(i);
end;
// --------------------------------------------------------------- //

and now Int32ToUTF8() is almost 10 times faster than InToStr():

    Classic InToStr timing = 1813 milli-seconds. sText = 10000000
    Int32ToUTF8 timing = 187 milli-seconds. sText = 10000000


The only problem is: I use String, not RawUTF8, in my projects. Whatever gain I enjoy from using Int32ToUTF8() is actually lost when converting back to string.

My question is: is there a similar routine that works with strings right away?

PS. The same question applies to other optimized routines. For instance, Trim, Pos, StringReplaceAll, etc... they all gave me really good results, but they also use RawUTF8.

Thanks!

#5 Other components » SynCommons.pas Int32ToUTF8 question » 2012-12-19 07:01:42

style-sheets
Replies: 9

Hi,

I was looking for a faster IntToStr implementation and discovered SynCommons.pas.

I read in the comments that should be 3x faster than the normal implementation, I tried this Delphi 2010 code, but I'm not sure if I'm using/interpreting the results correctly:

// ----------------------------------------------------------- //
procedure TForm1.Button1Click(Sender: TObject);
var
   sText   : String;
   TheTime : Integer;
   i       : Integer;
begin
     TheTime   := GetTickCount();
     for i := 1 to 10000000 do    // Repeat the tests 10 million times
         sText := IntToStr(i);
     Memo1.Lines.Add('Classic InToStr timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds. sText = ' + sText);

     TheTime   := GetTickCount();
     for i := 1 to 10000000 do    // Repeat the tests 10 million times
         sText := Int32ToUTF8(i);
     Memo1.Lines.Add('Int32ToUTF8 timing = ' + IntToStr(GetTickCount() - TheTime) + ' milli-seconds. sText = ' + sText);
end;
// ----------------------------------------------------------- //

Int32ToUTF8() is only 20 or 30 milli-seconds faster than IntToStr().

I'm not familiar with UTF8, I suspect some conversion is slowing Int32ToUTF8() down

Am I missing something here?

Thanks!

Board footer

Powered by FluxBB