-
Content Count
1518 -
Joined
-
Last visited
-
Days Won
154
Everything posted by Stefan Glienke
-
To avoid repeating the unit throughout the source code, you can declare an alias at the top and only explicitly put the unit name there. That, however, only works for non-generic types and consts. I wish it would also work for generics and routines.
-
The claim that it compiles faster is bogus - prove me wrong. Most compile time from spring4d comes from generics, which I reported years ago. Also, my suggestion for third-party libraries is to pre-compile them, which removes any dependency on the project options in your project. Currently, Spring4d supports down to XE, and as long as that is the case, I am not putting even more conditionals into the code than there already are.
-
Why?
-
TParallelArray Sort Performance...
Stefan Glienke replied to Steve Maughan's topic in RTL and Delphi Object Pascal
Just a few new numbers of a not yet released parallel pdq sort - using the benchmark code from this comment earlier in this thread Fill array (double), elements count: 500000 Start sorting ... RTL TArray.Sort (ms.): 47 RTL TParallelArray.Sort (ms.): 35 Spring TArray.Sort (ms.): 12 Spring TArray.Sort_Parallel (ms.): 3 Fill array (double), elements count: 5000000 Start sorting ... RTL TArray.Sort (ms.): 551 RTL TParallelArray.Sort (ms.): 128 Spring TArray.Sort (ms.): 136 Spring TArray.Sort_Parallel (ms.): 64 Fill array (double), elements count: 100000000 Start sorting ... RTL TArray.Sort (ms.): 12724 RTL TParallelArray.Sort (ms.): 1884 Spring TArray.Sort (ms.): 3035 Spring TArray.Sort_Parallel (ms.): 675 Again - these numbers are fluctuating a bit because the benchmark is a "run once" benchmark and it depends on the current CPU state etc - also I did not tweak the threshold and CPU count yet - simply calling TTask.Run from System.Threading to fork some slices into parallel execution. But overall it does not look too bad, doesn't it? -
Of course, he says that - he wants to sell his overpriced garbage
-
Guidance on FreeAndNil for Delphi noob
Stefan Glienke replied to Paul Dardeau's topic in RTL and Delphi Object Pascal
Because as you can read in this thread people advocate for using it everywhere instead of at those rare places it's designed for: making sure the reference is set to nil before the instance is destroyed because any code being called during destruction might reach back to this very reference. (which is the reason its name is not even correct - it should have been named NilAndFree) -
Guidance on FreeAndNil for Delphi noob
Stefan Glienke replied to Paul Dardeau's topic in RTL and Delphi Object Pascal
Using FreeAndNil is the very essence of https://en.wikipedia.org/wiki/Cargo_cult_programming -
Virtual class methods and properties
Stefan Glienke replied to pyscripter's topic in RTL and Delphi Object Pascal
It appears that Marco lacks the technical understanding to evaluate this issue. I left a comment. -
Guidance on FreeAndNil for Delphi noob
Stefan Glienke replied to Paul Dardeau's topic in RTL and Delphi Object Pascal
The issue with your code is that it captures Self - if you avoid that, your problems go away. -
Guidance on FreeAndNil for Delphi noob
Stefan Glienke replied to Paul Dardeau's topic in RTL and Delphi Object Pascal
Reducing instead of eliminating the probability of AVs (or other errors caused by races) in async code is one of the most annoying things you can do - anyone who ever was on the hunt for that "one in a billion times" bug knows that. I cannot believe that people who should know better give such advice. -
Guidance on FreeAndNil for Delphi noob
Stefan Glienke replied to Paul Dardeau's topic in RTL and Delphi Object Pascal
The best practice is coding in a way that you don't need it -
It always is just a matter of taste - I don't particularly like the parameter and local variable prefixing so I mostly settled on the C# naming conventions for those - I did not want to go that far to name fields with a leading underscore like them though. Though this is not without disadvantages - I had cases where I had a count parameter and wanted to access the Count field but without qualifying with Self I accessed the parameter instead. (those are the days where I wished for case sensitivity) Because being open source means that everyone can go ahead and modify it to their liking, right?
-
Looks great - as always: spring4d source for the real test and it seems to stumble at a few places where it then goes into "line breaks go to 11" mode - here for example: or
-
Looking but not finding...
Stefan Glienke replied to Rick_Delphi's topic in Job Opportunities / Coder for Hire
That comment didn't age well I guess -
Since February 2025, the creation of an 'ini' file with Delphi is much slower than in the past.
Stefan Glienke replied to Jean_D's topic in Windows API
I bet the C++ code does not do the same as TIniFile in Delphi which calls WritePrivateProfileString for every entry. -
Custom Managed Record - Compiler Fail "F2084 Internal Error C25335"
Stefan Glienke replied to rgdawson's topic in Algorithms, Data Structures and Class Design
Without saying too much there is the possibility that this issue (https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-2458) will be fixed in the next release. -
(FYI) Delphi can't optimize out unneeded inheritance
Stefan Glienke replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
I am all for better optimization performed by the compiler but this particular case is not among them - if you write empty methods then use some static code analysis to let them be detected and remove them. Optimizing out empty methods (and here we are not talking about some regular methods but ctor and dtor!) is something that most compilers don't do for various reasons. Only when methods get inlined (which is not possible for virtual methods unless devirtualization is possible but that's an entirely different story) the compiler can detect that there actually is nothing to (and calling inherited is not nothing) and in fact the Delphi compiler does that - but ctor and dtor can not be inlined. The case you show here gets more interesting though if you remove all the empty ctors and dtors because then I still see a slight difference of 10-15%. The reason for that is TObject.InitInstance P.S. Just FYI if I run the benchmark without the empty ctor and dtor in Delphi 12 release config I get these numbers: BaseClass: 106,01 ms unneeded inheritance: 119,40 ms The same code compiled in Delphi 10.1 gives these numbers - so much about "there is no progress on optimization": BaseClass: 156,23 ms unneeded inheritance: 175,53 ms Although these particular differences are most likely because of the following two improvements I provided: Better TObject.InitInstance Better _FinalizeRecord -
DevEx VCL Components & VCL Styles??
Stefan Glienke replied to Ian Branch's topic in Delphi Third-Party
There seems to be an adapter to apply VCLStyles to DevExpress components: https://www.almdev.com/prods/stylecontrols/stylecontrols.html - I have no experience with this but at some point we will have to look into this as customers keep asking for Dark mode in our application 😎 🙈 -
What new features would you like to see in Delphi 13?
Stefan Glienke replied to PeterPanettone's topic in Delphi IDE and APIs
You are comparing Win32/Debug with Win64/Release *cough* -
What new features would you like to see in Delphi 13?
Stefan Glienke replied to PeterPanettone's topic in Delphi IDE and APIs
Delphi developers.... one half still uses Delphi 7 and the other one does not even do 32-bit anymore -
CreateObservableList example in Spring4D
Stefan Glienke replied to Dave Novo's topic in Delphi Third-Party
All collections have events for getting notified of addition/removal via the OnChanged event - observable lists are something different. On those if the objects implement INotifyPropertyChanged they communicate to the list that a property has changed so the list then gets caChanged from those items. -
Case: Please Explain Why Inline Variable Prevents Compilation
Stefan Glienke replied to rgdawson's topic in RTL and Delphi Object Pascal
Most simple case to repro to compiler error: procedure X(i: Integer); begin end; procedure Y; begin var f: TFunc<Integer>; X(f); end; -
Get Index of enumeration in spring4D
Stefan Glienke replied to Dave Novo's topic in Delphi Third-Party
https://bitbucket.org/sglienke/spring4d/src/2.0.1/Source/Base/Collections/Spring.Collections.pas#lines-6391 -
Get Index of enumeration in spring4D
Stefan Glienke replied to Dave Novo's topic in Delphi Third-Party
First of all, you can already achieve what you asked for in two different ways. (As I said, I will look into adding a similar method as .NET 9 did, but it's not as easy due to Delphi's limitations - it most likely will be a static method on TEnumerable and not on IEnumerable because it returns a differently typed IEnumerable, and that causes the Delphi compiler to complain with E2604.) Apart from the obvious use of a classic for-to loop if you already have an indexable collection such as IList where that new method IMHO would make no sense and just add overhead you can do this: var indexedColl := TEnumerable.Zip<Integer,TMyClass>(TEnumerable.Range(0, myColl.Count), myColl); for var curItem in indexedColl do Writeln('index: ', curItem.Value1, ' - item: ', curItem.Value2.ToString); If you want more control over index generation you can write this: var indexedColl := TEnumerable.Select<TMyClass, Tuple<Integer,TMyClass>>(myColl, function(const item: TMyClass; const index: Integer): Tuple<Integer,TMyClass> begin Result := Tuple<integer,TMyClass>.Create(index, item); end); for var curItem in indexedColl do Writeln('index: ', curItem.Value1, ' - item: ', curItem.Value2.ToString); If you then want to filter only certain indexes you just call Where on indexedColl: var oddIndexes := indexedColl.Where( function(const tuple: Tuple<Integer,TMyClass>): Boolean begin Result := Odd(tuple.Value1); end); for var curItem in oddIndexes do Writeln('index: ', curItem.Value1, ' - item: ', curItem.Value2.ToString); -
Get Index of enumeration in spring4D
Stefan Glienke replied to Dave Novo's topic in Delphi Third-Party
This would be a duplication of the already existing Where