Leaderboard
Popular Content
Showing content with the highest reputation on 12/08/23 in Posts
-
I looked at sgcWebSockets today - but the price is really steep - I don't need the rest of the library but http/2 is only in the most expensive version - and then I need to get gprc working on top of that. I'm actually leaning towards doing this project in c# (the server is already c#) - testing with .net 8.0 AOT compilation so far produced a 4.5MB exe (+ a 12MB dll for google protocol buffers). Obviously it will be larger than that once done. As much as I want to use delphi for this project - the libraries are just not there - contrast to dotnet - grpc is a first class citizen (and the performance is impressive). I was able to get up and running in less than 10 minutes - contrast that to having spent most of today looking for a delphi grpc client that works.
-
IntToStr algorithm (Interesting read)
David Heffernan replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
From my codebase: // disable range checks and overflow checks so that Abs() functions in case Value = Low(Value) {$R-} {$Q-} function CopyIntegerToAnsiBuffer(const Value: Integer; var Buffer: array of AnsiChar): Integer; var i, j: Integer; val, remainder: Cardinal; negative: Boolean; tmp: array [0..15] of AnsiChar; begin negative := Value<0; val := Abs(Value); Result := 0; repeat DivMod(val, 10, val, remainder); tmp[Result] := AnsiChar(remainder + Ord('0')); Inc(Result); until val=0; if negative then begin tmp[Result] := '-'; Inc(Result); end; Assert(Result<=Length(Buffer)); i := 0; j := Result-1; while i<Result do begin Buffer[i] := tmp[j]; Inc(i); Dec(j); end; end; function CopyIntegerToWideBuffer(const Value: Integer; var Buffer: array of WideChar): Integer; var i, j: Integer; val, remainder: Cardinal; negative: Boolean; tmp: array [0..15] of WideChar; begin negative := Value<0; val := Abs(Value); Result := 0; repeat DivMod(val, 10, val, remainder); tmp[Result] := WideChar(remainder + Ord('0')); Inc(Result); until val=0; if negative then begin tmp[Result] := '-'; Inc(Result); end; Assert(Result<=Length(Buffer)); i := 0; j := Result-1; while i<Result do begin Buffer[i] := tmp[j]; Inc(i); Dec(j); end; end; function CopyInt64ToAnsiBuffer(const Value: Int64; var Buffer: array of AnsiChar): Integer; var i, j: Integer; val, remainder: UInt64; negative: Boolean; tmp: array [0..23] of AnsiChar; begin negative := Value<0; val := Abs(Value); Result := 0; repeat DivMod(val, 10, val, remainder); tmp[Result] := AnsiChar(remainder + Ord('0')); Inc(Result); until val=0; if negative then begin tmp[Result] := '-'; Inc(Result); end; Assert(Result<=Length(Buffer)); i := 0; j := Result-1; while i<Result do begin Buffer[i] := tmp[j]; Inc(i); Dec(j); end; end; function CopyInt64ToWideBuffer(const Value: Int64; var Buffer: array of WideChar): Integer; var i, j: Integer; val, remainder: UInt64; negative: Boolean; tmp: array [0..23] of WideChar; begin negative := Value<0; val := Abs(Value); Result := 0; repeat DivMod(val, 10, val, remainder); tmp[Result] := WideChar(remainder + Ord('0')); Inc(Result); until val=0; if negative then begin tmp[Result] := '-'; Inc(Result); end; Assert(Result<=Length(Buffer)); i := 0; j := Result-1; while i<Result do begin Buffer[i] := tmp[j]; Inc(i); Dec(j); end; end; {$IFDEF RANGECHECKSON}{$R+}{$ENDIF} {$IFDEF OVERFLOWCHECKSON}{$Q+}{$ENDIF} No heap allocation. I guess I could avoid that DivMod now and do something better. The main point is that a good runtime library should have building block functions like this that allow us to perform such conversions without forcing heap allocation. The RTL should have functionality like this on top of which all conversion functions can be built. Then the RTL function can be optimised and everyone benefits. -
IntToStr algorithm (Interesting read)
Stefan Glienke replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
I don't know what to think after reading that article. Here are my comments on it: - the classic way of truncating the last 2 digits with div and mod 10 (or 100) does not involve a costly div or mod instruction on modern compilers (*cough* even Delphi 12 now does it - apart from the bugs that came with it) - I think C++ compilers would detect doing a div and a mod instruction and the code they emit would be further optimized so it does not require the "workaround" that the Delphi RTL uses by calculating the modulo by subtracting the div result times 100 from the original value. - the pseudo-code he shows for detecting the number of digits is correct but this is never what gets executed - and you either rewrite this into a few branches (as you can see in the RTL), a C++ compiler might unroll the loop or some other trickery is applied The DivBy100 function was introduced by me in RSP-36119 and I already notified them that DivBy100 can be removed in 12 because now it properly optimizes a div by 100 - however, that affects performance only by like 0.5% or so. As David correctly pointed out the real bottleneck is the heap allocation - and not only a single one when you just turn an integer into a string and display that one but when you concat strings and numbers the "classic" way because then it produces a ton of small temporary strings. That issue even exists when using TStringBuilder where one might think that this was built for optimization. If you look into some overloads of Append you will see that it naively calls into IntToStr and passes that down to the overload that takes string. This is completely insane as the conversion should be done directly in place into the internal buffer that TStringBuilder already uses instead of creating a temporary string, convert the integer into that one, pass that to Append to copy its content into the buffer. This will likely be my next contribution as part of my "Better RTL" series of JIRA entries. -
Delphi 11.3 issue with iOS Today Extension widgets
Dave Nottage replied to Chris Pim's topic in Cross-platform
It was reported in https://quality.embarcadero.com/browse/RSP-42283, but there are a couple of other similar reports, e.g. https://quality.embarcadero.com/browse/RSP-42415 The problem is that PAServer signs the extension with the wrong entitlements, and in Chris' (and my) case, it's unnecessary because the extension has already been correctly signed, i.e. it does not even need to be touched. Replacing the extension in the .app bundle, and using iosinstall to install the it solves the problem, at least debugging-wise. I expect a similar process will be needed for repackaging the .ipa. -
Your code makes no sense. Instead of: value2 := random(500) + 1; while value2 < 251 do value2 := random(500) + 1; why don't you just: // Values from 251 to 500 value2 := 251 + random(250);
-
So you want 4 random values, one each in the ranges 1-250, 251-500, 501-750, and 751-1000, right: Try this: value1 := random(250) + 1; value2 := random(250) + 250; value3 := random(250) + 500; value4 := random(250) + 750; Each random number is restricted to a 250 range but adding a number to it puts it into different range brackets.
-
Just pointing out that is "debug stuff" of FastMM5, usually not compiled to release-binaries, but it depends on how exe is built... I've always used latest FastMM and never there has been proof that something was FastMM's fault. Not saying that it has always been bug free, but problems I've encountered always been at somewhere else, FastMM just had borough them into light. -Tee-
-
If someone do have an issue that is possible solved in latest commit why not trying? I can't think that an commit is made without testing first.
-
How to remove C++ from RadStudio 12 after installation?
FPiette replied to Bart Kindt's topic in VCL
Run Delphi personality only: add "-d Delphi" to the shortcut you use to launch the IDE. See the documentation: IDE Command Line Switches and Options -
I've been looking at that - since the DelphiGRPC makes use of it. Down the rabbit hole I go..
-
I have a client who wants to use DWScript to do structural load analysis of large models (thousands to millions of nodes). Since DWScript compiles to an AST (Abstract Syntax Tree) and then executes the objects in that tree, he was a bit concerned about performance. He had tried various other scripting systems and they were just too slow. So we did some benchmarking of a sequence of typical calculations in Delphi vs DWScript. As expected the Delphi compiled code was about 4 times faster than DWScript. The client thought that that was acceptable but I decided to try out the DWScript jitter anyway... As it turns out there might just be something to David's complaints about Delphi's math performance 😉 because with the jitter enabled DWScript was now more than twice as fast as the native Delphi code. Also, Delphi 64-bit was about 25% slower than 32-bit and 64-bit "optimized" was slower than "unoptimized". Not to take anything away from Eric Grange's amazing work on DWScript, but I would be embarrassed if my native code compiler was outperformed by a scripting system.
-
IntToStr algorithm (Interesting read)
David Heffernan replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
The biggest issue with the Delphi code is that it forces heap allocation on you which is the real bottleneck. -
Well. I learnt about something today. Recursive regexes.
-
Uninstalled D11, now D12 won't start....
Ian Branch replied to Ian Branch's topic in Delphi IDE and APIs
Resolved. Deleted both Parnassus BookMarks & CoreEditor entries in the registry just to be safe, then used AutoGetit to reinstall it/them. All good now. -
How should spaces after a comment be handled by the formatter
baka0815 replied to dummzeuch's topic in GExperts
I would also prefer a setting: 1. No space 2. Space 3. Line break 4. leave untouched I personally would prefer the "1 space" variant, but I would also not want to have a comment on the left of a statement. I would prefer the comment above or on the right. -
Spring4D 2.0 sneak peek - the evolution of performance
Stefan Glienke posted a topic in Tips / Blogs / Tutorials / Videos
https://delphisorcery.blogspot.com/2021/06/spring4d-20-sneak-peek-evolution-of.html