Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 12/08/23 in all areas

  1. Vincent Parrett

    GRPC Client

    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.
  2. 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.
  3. 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.
  4. Dave Nottage

    Delphi 11.3 issue with iOS Today Extension widgets

    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.
  5. Anders Melander

    random between a range

    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);
  6. corneliusdavid

    random between a range

    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.
  7. Tommi Prami

    FastMM 5 Performance

    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-
  8. Cristian Peța

    FastMM 5 Performance

    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.
  9. FPiette

    How to remove C++ from RadStudio 12 after installation?

    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
  10. Vincent Parrett

    GRPC Client

    I've been looking at that - since the DelphiGRPC makes use of it. Down the rabbit hole I go..
  11. Anders Melander

    Delphi 12 is available

    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.
  12. The biggest issue with the Delphi code is that it forces heap allocation on you which is the real bottleneck.
  13. pmcgee

    Removing String

    Well. I learnt about something today. Recursive regexes.
  14. Ian Branch

    Uninstalled D11, now D12 won't start....

    Resolved. Deleted both Parnassus BookMarks & CoreEditor entries in the registry just to be safe, then used AutoGetit to reinstall it/them. All good now.
  15. 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.
  16. https://delphisorcery.blogspot.com/2021/06/spring4d-20-sneak-peek-evolution-of.html
×