Jump to content

Stefan Glienke

Members
  • Content Count

    1357
  • Joined

  • Last visited

  • Days Won

    129

Everything posted by Stefan Glienke

  1. That code reminds me of what I have seen in SysUtils _IntToStr64 and _IntToStr32 (getting the number of digits) Also see https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
  2. Stefan Glienke

    IfThen Oddity...

    Because that is not pascal-ish! /s 🙄 P.S. Yes I know about proposals to make it look pascal-ish - I even think we discussed that in another thread already.
  3. People overuse generics and forget that the implementation often does not need generics at all: type TSupport = class helper for TObject private function __Supports(out ResObj: TObject; cls: TClass): Boolean; public function Supports<T: class>(out ResObj: T): Boolean; inline; end; function TSupport.__Supports(out ResObj: TObject; cls: TClass): Boolean; begin if Assigned(Self) and Self.InheritsFrom(cls) and not ((Self.InheritsFrom(TBoldObject)) and TBoldObject(Self).BoldObjectIsDeleted) then begin ResObj := Self; Exit(True); end; ResObj := nil; Result := False; end; function TSupport.Supports<T>(out ResObj: T): Boolean; begin Result := __Supports(TObject(ResObj), T); end; This code will not cause any bloat at all (in the final executable - see below for the situation during compilation though). What @ventiseis wrote is correct - the issues with long compile-time and possibly running ouf of memory (more so under the LLVM based compiler because they have a larger memory usage already) are real. They are caused by the compiler first compiling unit by unit and stuffing everything generic being used into each dcu just to (possibly) remove it again later during link time. Linker however will only remove exact identical duplicates such as if you have TList<TFoo> in multiple units executable will only contain it once, but it will also contain TList<TBar> and TList<TQux> even though they are also just lists for objects. Since XE7 most methods on TList<T> are marked as inline and unless you are using runtime packages they are not being called in your executable but the internal TListHelper ones but since all RTL classes have $RTTI turned on the binary will still contain all these methods. You only partially get rid of them by using {$WEAKLINKRTTI ON} which you need to put into each and every unit (years ago you could put that into the dpr and it affected all units but that was actually a compiler bug that made flags with scope local being global - but any unit that changed them then also changed them globally which caused quite some weird defects) That is why I did the huge refactoring in Spring4D regarding collections and the generic container registration API. If you use a list from spring with a thousand different classes the binary will only contain the code for the list once unlike with the RTL where you would have it a thousand times The issues are known and reported but obviously are not severe enough or too complex (especially the second one would require some architectural changes to how the compiler deals with generics): https://quality.embarcadero.com/browse/RSP-16520 https://quality.embarcadero.com/browse/RSP-18080
  4. Stefan Glienke

    Components4developers???

    Looks to be an issue with https - over http it works
  5. Stefan Glienke

    Function with 2 return values ?

    A static array of Double with the size 3 - exact type name would be context-specific and since you are not giving any context I cannot name it.
  6. Stefan Glienke

    Function with 2 return values ?

    A pair is a tuple where n is 2 - so yes it is a tuple
  7. Stefan Glienke

    Compiling a component for Win64

    It was a must if you have done a bit more than just registering a component (such as custom designers and stuff) because then the package requires designide.bpl which you must not ship. Yet the IDE even in 11.1 creates new packages as design&runtime 🙄
  8. That's up to the implementation of ReallocMem - the one that comes with Delphi (FastMM4) (I just looked into getmem.inc) has this comment:
  9. Stefan Glienke

    TMethodImplementation and its uses

    FWIW I only use this to make my multicast events work on platforms where I don't have exactly that: handcrafted assembly code to do the parameter passing. And these run hundreds of times faster than using RTTI. You can turn on using RTTI instead of the asm code in Spring.Events Here is a simple benchmark result: asm (win32) Event invokes/ms: 14925 rtti Event invokes/ms: 205 I have already started digging more into the TMethodImplementation class to optimize its use for those platforms where I don't have the handcrafted asm. There are also libraries that avoid the overhead of the Delphi RTTI to do dynamic invocation by handling all the low level details: https://github.com/d-mozulyov/Tiny.Library#rtti but that requires doing the parameter passing via some stubs written in c asm
  10. You don't need to manually create tasks - just use a TParallel.For and do proper partitioning - I wrote an answer on Stackoverflow about that subject some while ago. The code there which did some array processing should be easily be adaptable to your usecase
  11. Stefan Glienke

    Cromis.DirectoryWatch range error

    The WParam of TMessage is ultimately of type NativeUInt while the WParam parameter is of type Longint. Since Delphi 11 the default Debug config has Range and Overflow checks enabled which causes any signed to unsigned or vice versa assignment to possibly raise a range check error. Strictly speaking any assignment of signed to unsigned and vice versa is a potential defect - you can reveal them by turning W1071 on with {$WARN IMPLICIT_INTEGER_CAST_LOSS ON}
  12. You forgot "no calling each other nazi" (see Godwin's law)
  13. Using FastMM with the setting to mark freed memory with a certain pattern ($80808080 by default iirc) would have revealed that issue within a few minutes fwiw.
  14. Stefan Glienke

    Do you need an ARM64 compiler for Windows?

    By that logic the Delphi team must be located near Piacenza 🙄
  15. Stefan Glienke

    EMonitorLockException help needed

    Only from TMonitor.CheckOwningThread (indirectly via the lookup mechanism from ErrorProc in ErrorAt) which gets called from two places: TMonitor.Exit and TMonitor.Wait.
  16. Stefan Glienke

    EMonitorLockException help needed

    My point is that posting a red herring won't get you much help. First task should be to get a proper call stack because that will directly point you to the source location that causes it without the need to poke in the dark hoping to find it. The exception is clear and this happens when a monitor lock is being exited or waited on from a different thread than the one that entered it.
  17. Stefan Glienke

    EMonitorLockException help needed

    The Eurekalog call stack makes zero sense compared to the code on github. Either you are using some outdated code or modified something yourself. There is nothing monitor in TThreadSafeQueue.Enqueue. It is using a critical section
  18. My profile shows what I am using in production at work. That does not mean I don't also have access to 11.1 which had this issue addressed 😉
  19. Fun fact: it does with {$WARN IMPLICIT_CONVERSION_LOSS ON} (which is not turned on by default - probably because it would produce a ton of those in existing code)
  20. IIRC in Delphi 7, you have to list all fields in a const record declaration while in later versions you can omit some as I did - they are then automatically initialized by their default value. And depending on the usage of such a record they don't matter like in my case because I never need the CurrencyString. And you don't need it either because JSON has no currency representation. If you need that usually its represented by different fields, the amount and the currency abbreviation Personally, I could not care less about a Delphi version from almost 20 years ago lol
  21. The solution is to use the FloatToStr overload that takes a TFormatSettings and pass one that has DecimalSeparator set to dot. I typically declare such a TFormatSettings as const and fill all the fields that are required for JSON or some other textual format like this - the following for example is being used in Spring for converting various data types to string (from TValue): const ISO8601FormatSettings: TFormatSettings = ( DateSeparator: '-'; TimeSeparator: ':'; ShortDateFormat: 'YYYY-MM-DD'; LongDateFormat: 'YYYY-MM-DD'; TimeAMString: ''; TimePMString: ''; ShortTimeFormat: 'hh:nn:ss'; LongTimeFormat: 'hh:nn:ss'; DecimalSeparator: '.'; );
  22. Stefan Glienke

    Do you need an ARM64 compiler for Windows?

    Yes, just as much as it was just recompiling VS for x64.
  23. This is a pointless endeavor unless you have some proof that the new code in Delphi 11 has a performance regression - the generated assembly code for the purepascal code is almost identical to the handwritten version before on x86 and all other platforms it should be significantly faster than the previous pure pascal implementation. (I should know - I did that change)
  24. You do a sort of the group by criteria 1-3, then you check if there are any ties between teams and build a subset of those teams and do a sort on those by criteria 4-6. That second step is actually similar to the first just that you don't have a full group but only 2 or 3 teams and the results of the matches between those.
×