Jump to content

Stefan Glienke

  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by Stefan Glienke

  1. Stefan Glienke

    Maximum static memory

    If your quicksort is taking 80% of the time then its implementation very likely is garbage. Worst case scenario for QuickSort is O(n²) which is why usually one should not use pure QuickSort but IntroSort which mitigates against the worst case. Also depending on the type of the elements you are are sorting the swapping can be ridiculously expensive and in case you are using the generic RTL implementation from TArray it does not do that very well.
  2. Stefan Glienke

    ANN: DDevExtensions is now on GitHub

    Created PR https://github.com/ahausladen/DDevExtensions/pull/9
  3. Stefan Glienke

    RAD Studio 11 Alexandria is now available

    Has nothing to do with the debugger but with a refactoring to TList which I suggested: https://quality.embarcadero.com/browse/RSP-34681 (probably cannot see that as it still seems to be marked as beta report)
  4. Stefan Glienke

    The state of GExperts Support for Delphi 11

    To be honest - after your fixes, it's even worse than it was before under HighDPI. I was using GExperts during beta - it was not beautiful but most dialogs could be used. Now it looks like this:
  5. Stefan Glienke

    RAD Studio 11 Alexandria is now available

    You're welcome - it is just a slightly improved version of what Aleksandr Sharahov already wrote years ago. Surprisingly they never used his purepascal code which compiles to almost the exact same code as the x86 asm version was doing. There are more than a dozen other improvements in the RTL that I have worked on - I cannot fix their compiler but I can certainly improve some suboptimal RTL code.
  6. Stefan Glienke

    Maximum static memory

    I recommend SampingProfiler which simply works with either map file or td32 info in the exe. If you use the map2pdb Tool that Cristian linked you can use Intel VTune or uProf
  7. Stefan Glienke

    Maximum static memory

    I am absolutely putting my bet on this. The second issue after that will most likely be a non-cache-friendly access pattern. But you don't have to guess - run the code under a profiler and it will tell you the slow parts.
  8. Just to make sure: this offset depends on how many fields your object has and how many interfaces it implements - the IMT slots always follow after the fields. For more info take a look into "Delphi in a nutshell"
  9. Looks like a compiler defect - when changing this declaration: TOnMyIntfItemSelected<T: IMyIntfItem> = procedure(AItem: IMyIntfItem) of object; the code for TMyIntfItemA<T>.Select looks like this: List.Intf.pas.82: begin 007083E4 53 push ebx List.Intf.pas.83: if Assigned(FOnItemSelected) then 007083E5 6683781200 cmp word ptr [eax+$12],$00 007083EA 7411 jz $007083fd List.Intf.pas.84: FOnItemSelected(Self); 007083EC 8BD0 mov edx,eax 007083EE 85D2 test edx,edx 007083F0 7403 jz $007083f5 007083F2 83EAE8 sub edx,-$18 // this is where it turns Self into an IMyIntfItem, $18 is the offset where the interface method table pointer sits inside the object 007083F5 8BD8 mov ebx,eax 007083F7 8B4314 mov eax,[ebx+$14] 007083FA FF5310 call dword ptr [ebx+$10] List.Intf.pas.85: end; 007083FD 5B pop ebx 007083FE C3 ret but when it has the generic T parameter it looks like this: List.Intf.pas.82: begin 007083E4 53 push ebx List.Intf.pas.83: if Assigned(FOnItemSelected) then 007083E5 6683781200 cmp word ptr [eax+$12],$00 007083EA 740A jz $007083f6 List.Intf.pas.84: FOnItemSelected(Self); 007083EC 8BD8 mov ebx,eax 007083EE 8BD0 mov edx,eax // here it simply passes Self 007083F0 8B4314 mov eax,[ebx+$14] 007083F3 FF5310 call dword ptr [ebx+$10] List.Intf.pas.85: end; 007083F6 5B pop ebx 007083F7 C3 ret To explain this a bit more: when putting an interface type as generic type constraint this means for the compiler that the type you put for the generic type argument not only has to be that interface type but also that it can be a class that implements this interface. TMyIntfItemA<T> does this and thus satisfies the compiler when passing it to the argument of that event handler. However, inside the event handler, it is being treated as an interface and due to the lacking const parameter the compiler inserted an IntfAddRef call which blows up as the parameter that was passed was not really an interface reference but an object reference. Putting the const parameter makes it blow up a bit later though, namely when accessing Caption.
  10. If you don't want instances, then don't make it a class - this ain't Java.
  11. Stefan Glienke

    Console Manager for the Delphi IDE

    The question is this: do you want to get a wide adoption rate of something you've built or do you want to get two and a half coffees paid. As for how the console is done: Visual Studio Code simply communicates via stdin/stdout/stderr - see https://vscode.readthedocs.io/en/latest/editor/integrated-terminal/
  12. Stefan Glienke

    We use DUnitX and it discovers all our silly mistakes before release

    Working on some better integration and result format that can be consumed by state of the art tooling such as https://github.com/danielpalme/ReportGenerator or https://github.com/marketplace/codecov but thats a side project that I don't spend much time on. Also still fighting some spurious crashes with DelphiCodeCoverage that result from it putting its breakpoints where it really should not (I suspect some incorrect debug information from the map file).
  13. This issue is as old as generics are: https://quality.embarcadero.com/browse/RSP-10506
  14. If your experiments are not just for educational purposes try out Spring - the container can do exactly that.
  15. Stefan Glienke

    10.4.1+ Custom Managed Records usable?

    IMO the only true way to do this in pascal is as they done in Oxygene - see "if expressions": https://docs.elementscompiler.com/Oxygene/Delphi/NewFeatures/
  16. Stefan Glienke

    10.4.1+ Custom Managed Records usable?

    I don't know what you mean 😇
  17. Stefan Glienke

    10.4.1+ Custom Managed Records usable?

    Not quite - this is the null coalescing operator ?: is a special version of the conditional operator - it is short for "if <expr> is not null then give <expr> else give <something_else>" Null propagation operator ?. is a special member access operator - short for "if <expr> is not null then access <expr>.<some_member> else do nothing or return null" Given that Delphi does not have a conditional operator I would assume that even though we might get language support for nullable types (reference types fall into that category) we don't get the null coalescing operator but chances are that we get a null propagation operator - but that is just me assuming things.
  18. Stefan Glienke

    10.4.1+ Custom Managed Records usable?

    You are most likely referring to the null propagation operator because there are plenty of nullable type implementations around.
  19. Stefan Glienke

    10.4.1+ Custom Managed Records usable?

    If you are a seasoned Delphi developer you know that new features are not usable for like half a decade or so...
  20. Code that originated in a Version before 2009
  21. If you have a bad compiler that puts cold code into the middle of your hot loop where performance really matters instead of restructuring the code you need goto.
  22. And you indeed refactored it into the only sane form I can think of! Might have moved the Result := False into that final else though because it's only needed then. And could have replaced the softcast with a hardcast because you already did the is check.
  23. Certainly but that would change the behavior - currently if the class is found it exits, regardless. With a giant if and/or statement it would continue to evaluate the is checks.
  24. Stefan Glienke

    upcoming language enhancements?

    We know they never do that but rather hope they be ready when they ship which also as we know it not the case either.