Jump to content

Leaderboard


Popular Content

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

  1. The DDevExtensions 2.85 and the DFMCheck 1.6 are now available for Delphi 10.3 Rio. DDevExtensions Changelog Added: Support for Delphi 10.3 Rio Added: Use Unit dialog option “Every unit on a single line” Improved: UnitSelector Dialog in Delphi 2009 opens much faster Fixed: Structure-View search dropdown had a max height of 2 items Downloads
  2. I have just uploaded the third beta version of GExperts 1.3.12 for Delphi 10.3 Rio. NOTE: This is still a BETA! Also note that this is for Delphi 10.3 Rio only. It won’t work with any other versions. This beta release contains a (ugly) work around for the redraw bug in the Goto-Dialog enhancement when theming is enabled. Also, a few other bugs have been fixed. I am not aware of any more bugs that are specific to this version of GExperts or Delphi 10.3 Rio. If you still find some, please report them on SourceForge. Also note, that I have still not tested the installer as I don’t have a fresh Delphi 10.3 installation for that test. https://blog.dummzeuch.de/2018/12/08/gexperts-1-3-12-beta-3-for-delphi-10-3-rio-available/
  3. I've just released the next version of OmniPascal. It's coming with support for the inherited keyword, type helpers and inline variables. http://blog.omnipascal.com/omnipascal-0-17-0-inherited-keyword-type-helpers-and-inline-variables/
  4. As expected. I think we now all agree on how it works 🙂
  5. I ran a test in Rio and it works quite well: type TTestObj = class public constructor Create; destructor Destroy; override; end; constructor TTestObj.Create; begin inherited Create; Writeln('TTestObj.Create'); end; destructor TTestObj.Destroy; begin Writeln('TTestObj.Destroy'); inherited; end; procedure Test; begin Writeln('Test started'); begin var obj := Shared.Make(TTestObj.Create)(); Writeln('obj = ', obj.ClassName); Writeln('End of nested scope'); end; Writeln('Test completed'); end; Output: Test started TTestObj.Create obj = TTestObj End of nested scope Test completed TTestObj.Destroy Inline var object is not destroyed at the end of scope, but at the end of the method. Still, that's something I more or less expected. Other than that, the code works fine. For the record, this can also be achieved with the "traditional" syntax. Delphi will kindly keep the interface alive until the end of the method: procedure Test; var obj: TTestObj; begin Writeln('Test started'); obj := Shared.Make(TTestObj.Create)(); Writeln('obj = ', obj.ClassName); Writeln('Test completed'); end; And there's also a bit slower but shorter variation to create a shared object: Shared<TTestObj>.Make() Just saying 😉
  6. Interestingly, that is quite similar to one of the reasons why "with" was invented in the first place: when accessing the record memory is costly. From Pascal User Manual and Report (emphasizes by me):
  7. Uwe Raabe

    Quoting quotes

    Drag-Select all the text you want to quote and click on the little "Quote" hint appearing when your selection is finished. That is also a good way to quote only part of a post and I miss that feature already in the German forum.
  8. As pointed out In another post by @Primož Gabrijelčič, in Delphi Rio you can just write: var s := Shared.Make(TStringList.Create); What an amazing hack Shared is! Also impressive type inference from Delphi.
  9. The ISafeGuard approach is not a smartpointer but creating a scope to some resource. There is a important difference: a smart pointer combines the resource and its lifetime management into one entity. Also the record based approach is the most naive one - while Spring4D offers this one as well it has a more advanced one. As for performance: measure it yourself: program MeasureIt; {$APPTYPE CONSOLE} uses Spring, Diagnostics, Classes, SysUtils, JclSysUtils; const ADD_COUNT = 10; CREATE_COUNT = 100000; procedure MeasureSpring; var s: IShared<TStringList>; i: Integer; begin s := Shared.Make(TStringList.Create); for i := 1 to ADD_COUNT do s.Add(i.ToString); end; procedure MeasureJcl; var s: TStringList; g: ISafeGuard; i: Integer; begin s := TStringList.Create; Guard(s, g); for i := 1 to ADD_COUNT do s.Add(i.ToString); end; procedure MeasureClassic; var s: TStringList; i: Integer; begin s := TStringList.Create; try for i := 1 to ADD_COUNT do s.Add(i.ToString); finally s.Free; end; end; procedure Main; var sw: TStopwatch; i: Integer; begin sw := TStopwatch.StartNew; for i := 1 to CREATE_COUNT do MeasureSpring; Writeln(sw.ElapsedMilliseconds); sw := TStopwatch.StartNew; for i := 1 to CREATE_COUNT do MeasureJcl; Writeln(sw.ElapsedMilliseconds); sw := TStopwatch.StartNew; for i := 1 to CREATE_COUNT do MeasureClassic; Writeln(sw.ElapsedMilliseconds); end; begin Main; Readln; end. The implementation in Spring 1.2.2 (currently released version) uses very optimized code for the smart pointer itself avoiding the overhead of an object allocation and all the code associated with it but only allocates a 12 Byte (32bit) block with the IMT. Since IShared<T> is not a regular interface but an anonymous method you can directly access the members of the underlying type. Yes, there is a method call every time but as you can measure that does not cause any significant overhead (unless you call .Add a million times). And even then the actual work being performed totally outweighs the smart pointer overhead
×