You are not logged in.
Ah that was it
Very interesting and confusing. Thanks!
EDIT:
Why do I get these warnings?
var
Str: RawUTF8;
A: RawUTF8;
function ExtractBetween(const Value, A, B: RawUTF8): RawUTF8;
var
aPos, bPos: Integer;
begin
result := '';
aPos := SynCommons.Pos(A, Value);
if aPos > 0 then
begin
aPos := aPos + Length(A);
bPos := SynCommons.PosEx(B, Value, aPos);
if bPos > 0 then
begin
result := Copy(Value, aPos, bPos - aPos);
end;
end;
end;
begin
A := '中'; //[dcc32 Warning] Project3.dpr(32): W1062 Narrowing given wide string constant lost information
Str := '中國哲學書電子化計劃';
A := ExtractBetween(Str, '中國', '計劃');
if A = '哲學書電子化' then
WriteLn('Parsed Correctly.');
ReadLn;
end.
But how else do you find true position of some chinese substring in a large text?
Hi!
Seems a bug in SynCommons.pas ?
program Project3;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, SynCommons;
var
Str: RawUTF8;
SubStr: RawUTF8;
I: Integer;
begin
Str := 'ийскf';
SubStr := 'к';
I := SynCommons.PosEx(SubStr, Str); // I := 7 ??? It should be 3
end.
EDIT:
Ah! It seems I need to div SizeOf(Char);
Ofcourse you can manipulate cookies! The problem is SynCrt didn't implement it... sadly.
Will need to make my own wrapper.
How to manage cookies with Synopse WinHTTP ? Is there something like TIdCookieManager for WinHTTP?
Does SynCommons.pas have fast routines for this? They aren't very optimized in XE6..
Is better to use threadvar IMHO. Locks are slower, much slower.
Random() is not thread safe at all. Because it is not a thread var. Plus 64 bit is a lot slower since its written in ASM.
Is there an alternative for this RTL random generator? It is not very fast or accurate.
An SSE optimized version would be nice but i cannot find any in SynCommons.pas
dwUtils.pas has a super fast version of IntToStr32/64 Unicode version ofcourse.
IMHO UTF8 is not worth it. Too many problems. You end up working AGAINST the compiler.
But if you want even more raw performance you should write it with ICC(Intel C++).
Does SynCommons.pas have a faster routine than Delphi for PAnsiChar, AnsiString to String conversions? Converting PAnsiChar to String is very costly in Delphi XE5.
What is the license of SynCommons? I would like to extract all the low level RTL replacements and add it in to a more light unit. With your license ofcourse.
There is no need for syncommons optimized move. ScaleMM2 has added this for SSE3.
Actually is not the same. Your supports SSE2 MAX! That one supports from MMX - SSE3. Now cpus support SSE 4.1, 4.2 etc
So not the same.
Hello!
Here is an MMX, SSE, SSE2, SSE3 optimized Move function but AFAIK it don't support x64.
Maybe possible to include in SynCommons.pas
Sorry I meant UTF16.
I agree but Eric's implementation works with UNICODE. And that will work with rest of components and that needs no to mess with conversions.
Yes but easier to maintain IMHO... it is the future of Delphi like it or not. In 5 years it will be standard.
Will framework use namespaces?
Ah we found TWriteOnlyBlockStream. Which is about 10x faster than TTextWriter when using regular strings. It is about 20ms faster when TTextWriter is using UTF8.
Yes only lazarus doesn't support it however what I remember, any Delphi version after Delphi 7 supports it. But that doesn't mean FPC will not support it in the future!
Syn.Common.pas
Syn.Compression.pas
and so on..
Yes it would be very much great to split it in to namespaces much like newer versions do it..
System.Sysutils
System.Types
etc..
IMHO better to use TMemoryStream to write / append and it will have similar performance and much better than TStringBuilder
For us SynCommons.pas is too complex / bloated.
Yes but where to do the conversions for example? When interfacing?
Agree but you cannot use any functions in new version because whole unit/project based on RAWUTF8
Only slightly by a couple of ms. Not much. But RawUTF8 string is alot faster. However you cannot use it with VCL/RTL in newer versions.
Due to constant conversions..
program Project6;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Diagnostics,
SynCommons;
var
TW: TTextWriter;
SW: TStopwatch;
StrA: String;
StrB: RawUTF8;
i, j: Integer;
begin
j := 100000;
StrA := 'test string';
StrB := 'test string';
SW := TStopwatch.Create;
TW := TTextWriter.Create(nil);
TW.CreateOwnedStream;
// delphi UTF16
SW.Start;
for i := 0 to j do
TW.AddString(StrA);
SW.Stop;
TW.Flush;
TW.CancelAll;
WriteLn('String: '+SW.ElapsedMilliseconds.ToString());
SW.Reset;
// RawUTF8
SW.Start;
for i := 0 to j do
TW.AddString(StrB);
SW.Stop;
TW.Flush;
TW.CancelAll;
WriteLn('RawUTF8: '+SW.ElapsedMilliseconds.ToString());
SW.Reset;
// StringToUTF8
SW.Start;
for i := 0 to j do
TW.AddString(StringToUTF8(StrA));
SW.Stop;
TW.Flush;
TW.CancelAll;
WriteLn('StringToUTF8: '+SW.ElapsedMilliseconds.ToString());
Readln;
end.
Yes but i think there is performance penalty regardless of implicit or explicit. String(RawUTF8) or RawUTF8(String)..
Anyway {$WARN IMPLICIT_STRING_CAST OFF} is the solution for using Syncommons.pas from XE4. Nasty solution but it works.
I will try to convert TTextWriter to use String without UTF8 fiasco
@ab but how to store regular unicode string types in TTextWriter? Do we have to use UTF8ToString / StringToUTF8 ? This would be very very inefficient if used in a loop. IMHO SynCommons.pas is unusable because of this on newer versions.
It would be good to add something like this..
procedure TTextWriter.AddString(const S: String);
begin
..
end;
Reason?
[dcc32 Warning] unit.pas(76): W1057 Implicit string cast from 'Char' to 'RawUTF8'
[dcc32 Warning] unit.pas(79): W1057 Implicit string cast from 'RawUTF8' to 'string'
Or atleast some switch to turn RawUTF8 = String.
TTextWriter needs to be renamed because there is an exact same class in System.Classes in XE4 Update 1!
RTL/VCL needs to recompile to strip the RTTI out.
I agree but 700kb is added to Console application using XE4 Update 1 - 32 bit. Just for using TTextWriter. I think SynLZ could be added with a compiler switch.
I doubt 700kb is only for TTextWriter respectively..
More readable? It needs a simple "Result := Self" in the function. I am sure you can add this to the unit.
The problem I see with SynCommons.pas is that its too big. It adds 2mb to debug and 600kb to a console application just
by using TTextWriter. There seems to be a lot of dead code left !
program Project6;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
SynCommons;
var
TW: TTextWriter;
begin
TW := TTextWriter.Create(nil);
TW.CreateOwnedStream;
try
WriteLn(TW.AddString('Hello').AddString(' from').AddString(' Synopse forums!').Text);
finally
TW.Free;
end;
Readln;
end.
Hello!
Is it possible to add the TStringBuilder Append way of adding things?
For example now in TTextWriter there is AddString but you cannot do this
TStringBuilder.Append().Append().Append() .. etc
Thanks!
Yes but i think an implementation based on THeapMemoryStream would be very very fast. Because TStringList has advantages over TStringBuilder but it consume a lot of memory!
Is there a fast implementation of TStringList like object? Based on TStringBuilder or DynArray?
There is ofcourse TRawUTF8List but its about 100ms slower than regular TStringList.
Yes but it would be nice if you could provide a 64 bit .obj file.
DISQLite3 supports 64 bit since ages!
EDIT: We decided to use UNIDAC.
Ah yes so we need to compile 64 bit our self to get .obj? I really don't like dll mess
Does SynCommons contain a fast dynamic array which dont use LOCK instructions?
Also is it possible to use sqlite3 with SynSQLite3 without dll? In 64 bit?
Why not patch these functions in runtime? LStrAsg etc. ?
What about a lock free dynamic array ? Many thanks!
So TTextWriter can be used as a String replacement?
So only solution is to modify System.pas? But i guess how to recompile? They add these stupid locks everywhere.
With this lock isn't called.. LStrAsg is called and LOCK is skipped.
procedure Test(const A,B:Integer; var Return:RAWUTF8);
begin
Return := 'A';
end;
Correct way of using?
C++ Builder has these problems aswell?
I think this needs to be fixed on compiler side. Fiddling with code is waste of time and productivity. If you fix the string then you still other components that use it. So it is pretty much pointless. Must be fixed by Embercadero..
Oh I forgot to mention this was compiled with Delphi XE5. And analyzed with Dissasembly tool via Delphi Debugger.
I almost get the same result with function. So this solution doesn't really do anything..
I think this happens only when you use old old compilers such as D7. But not new.
function Test(const A, B, C: Integer):String;
begin
Result := 'Test';
end;
Turns to:
TForm2.Test:
005B4910 55 push ebp
005B4911 8BEC mov ebp,esp
005B4913 83C4F4 add esp,-$0c
005B4916 894DF4 mov [ebp-$0c],ecx
005B4919 8955F8 mov [ebp-$08],edx
005B491C 8945FC mov [ebp-$04],eax
005B491F 8B4508 mov eax,[ebp+$08]
005B4922 BA40495B00 mov edx,$005b4940
005B4927 E8604DE5FF call @UStrAsg
procedure Test(const A, B, C: Integer; var Return:String);
begin
Return := 'Test';
end;
Turns to:
TForm2.Test:
005B4918 55 push ebp
005B4919 8BEC mov ebp,esp
005B491B 83C4F4 add esp,-$0c
005B491E 894DF4 mov [ebp-$0c],ecx
005B4921 8955F8 mov [ebp-$08],edx
005B4924 8945FC mov [ebp-$04],eax
005B4927 8B4508 mov eax,[ebp+$08]
005B492A BA48495B00 mov edx,$005b4948
005B492F E8584DE5FF call @UStrAsg
The more important question not raised here is.. What to use instead of "string" ??
The problem is that "var" also adds this "call @UStrAsg"
with this procedure Test(const A, B, C: Integer; var Return: String);
So what is real example on how to solve this?
Well hopefully mpv can provide some examples on how to use it. Specifically how to add new functions etc.