-
Content Count
1366 -
Joined
-
Last visited
-
Days Won
130
Everything posted by Stefan Glienke
-
JCL installation problems in D10.4.2
Stefan Glienke replied to TurboMagic's topic in Delphi Third-Party
That implies that there is nothing more than some code to compile - fwiw this does not even add the dcu output directory to the library path (which is my biggest issue with that "process") let alone all the other stuff the jcl/jvcl installer might do (I am no jedi dev, so I don't know how much of that is actually necessary). -
JCL installation problems in D10.4.2
Stefan Glienke replied to TurboMagic's topic in Delphi Third-Party
What process is that? -
Performance - Find duplicates: Iteration vs Binary Search
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Did you just ask if O(log n) is faster than O(n)? -
recompiling delphi source for Delphi Sydney
Stefan Glienke replied to Dave Novo's topic in RTL and Delphi Object Pascal
Generics as well but that is related to inlining because generics use a similar mechanism as inlining does. That's why we had some breaking changes in some updates in the past because some devs at Embarcadero obviously forgot about that and fixed some issues in Generics.Collections. I think there are more reasons for F2051 to happen but those that are not solvable by switching around compiler options are those I mentioned to my knowledge. To be honest I am still not fully understanding how inlining is being controlled exactly. For example when I write a for in loop over a TCollection in my code and add System.Classes to my project causing a recompile I see that it does not fully inline but does a call to TList<TCollectionItem>.GetItems which is marked as inline. When I use the dcu shipped with Delphi that call is not there. Changing $INLINE option does not change anything about that. Example code - when looking at the asm you will see the call I mentioned before. When the path to the pas file is removed and it uses the dcu the call is not there. I did not find a compiler option that makes it go away when compiling the pas file. uses System.Classes in 'c:\program files (x86)\embarcadero\studio\21.0\source\rtl\common\System.Classes.pas'; procedure Main; var list: TCollection; item: TCollectionItem; begin list := TCollection.Create(TCollectionItem); list.Add; for item in list do; end; begin Main; end. -
recompiling delphi source for Delphi Sydney
Stefan Glienke replied to Dave Novo's topic in RTL and Delphi Object Pascal
This has nothing to do with the compiler options but with the inlining - in Vcl.ExtCtrls.TCustomGridPanel.Loaded there is a for in loop over a TCollection and the GetCurrent implemenentation is different in 10.4 as it was in 10.0. To my knowledge there is no way to compile individual units that have methods that are inlined when being used in other units - so you have to compile the other units as well - in this case you also have to add Vcl.ExtCtrls to your project and recompile that as well even though you did not change anything in that unit but because of the inlined method. This can pile up quite significantly causing the necessity to recompile almost the entire codebase depending on which unit you modified and recompile. -
Fast lookup tables - TArray.BinarySearch vs Dictionary vs binary search
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Neither - all hash tables that have a word when it comes to performance are using some contiguous block of memory (aka array/vector). Otherwise, any possible cache locality is just completely destroyed. -
Micro optimization: Math.InRange
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Simple: AValue-AMin causes an overflow when AMin is bigger than AValue. Your code is shifting the non-zero-based range to a zero-based range causing AValue to possibly become <0. In fact, running the very benchmark code Mike posted will cause it! -
Micro optimization: Math.InRange
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
And even that depending on the CPU generation can possibly be detected by the branch predictor because it's a fixed pattern. You need a random sequence of numbers that you check against. However, keep in mind what exact use case you are benchmarking vs what you actually use this function for. Is it random data that needs to be checked for in range? If you have a loop where at some point the counter is in range and at some point runs out of range then the loop counter itself should be limited to just run over the numbers that are in range. -
GNU License 🤦♂️ Some of the methods in that helper are obsolete since XE7 because we have Insert, Add, Delete for dynamic arrays. Most of the other methods are in Spring.pas TArray which is not a helper for the System.Generics.Collections one but reimplements its methods and adds its own. For the TArrayRecord<T> type Spring.pas has Vector<T> (the naming is taken from C++ where this is the dynamic array type name)
-
Micro optimization: Math.InRange
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Indeed here it's the opposite, due to the way it's written it always has to perform both checks (see my third point). But depending on what you do after the if it could be done completely branchless. -
Micro optimization: Math.InRange
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
While your assessment on Math.InRange is true (it is coded in a bad way plus the compiler produces way too many conditional jumps - https://quality.embarcadero.com/browse/RSP-21955) you certainly need to read some material on how to properly microbenchmark and how to read assembly. First of all, even though the Delphi compiler is pretty terrible at optimizing away dead code it might omit the if statement if there is nothing to do after it. Second - be careful if one of your loops spans multiple cache lines while others don't this affects the outcome slightly and can in such a case affect the result in a noticeable way. Third - with a static test like this you prove nothing - the branch predictor will do its job. If you want to benchmark the raw performance of one vs the other you need to give it random data which does not follow the "not in range for a while, in range for a while, not in range until the end" pattern -
Fast lookup tables - TArray.BinarySearch vs Dictionary vs binary search
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
An impressive number of implemented collections for sure but it's only compatible with FreePascal and from a quick look you won't easily make that code Delphi compatible. But thanks for mentioning it - I will certainly run some benchmarks to compare. -
Fast lookup tables - TArray.BinarySearch vs Dictionary vs binary search
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
@Dany Marmur Agreed - it's the job of runtime library developers to get the most out of their data structures and algorithms so the users of those libraries don't have to worry 99.9% of the time but just chose the reasonable type/algo for the job. Funny enough I am currently in the process to do exactly that for my library and can tell you that for the RTL it's certainly not the case, unfortunately. -
Is set a nullable type? (record constraint)
Stefan Glienke replied to Eugine Savin's topic in RTL and Delphi Object Pascal
No version ever compiled this code - I just checked with XE8 to 10.4 (all the latest update/hotfixes) Reported since 10.0.1 - see https://quality.embarcadero.com/browse/RSP-13198 -
Fast lookup tables - TArray.BinarySearch vs Dictionary vs binary search
Stefan Glienke replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
And then after you spent quite some time implementing this without defects that it would not be any faster than all the ready-to-use collection types or the actual performance improvement would be completely negligible. -
Do bug fix patches really require active subscription?
Stefan Glienke replied to David Heffernan's topic in General Help
@Remy Lebeau Selective perception? If a compiler is not a critical product function I don't know what is. -
Do bug fix patches really require active subscription?
Stefan Glienke replied to David Heffernan's topic in General Help
I think at least in Germany the court would say otherwise - keyword: Nachbesserung und Gewährleistung -
Good quality Random number generator implementation
Stefan Glienke replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
pcg32 should be easy enough to implement from the c code. -
Several F2084 Internal Error on Delphi 10.4.2
Stefan Glienke replied to Davide Angeli's topic in Delphi IDE and APIs
That's what QA said before 10.4.2 released -
Several F2084 Internal Error on Delphi 10.4.2
Stefan Glienke replied to Davide Angeli's topic in Delphi IDE and APIs
Or he just wants to see the correct values when inspecting them while debugging? -
Find exception location from MAP file?
Stefan Glienke replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
No need to assume or guess anything - the base addresses are in the map file. -
What type of collections do you have in mind? Not all types of collections can be implemented completely lock-free in an efficient way or they are hilariously complex to implement. Depending on the implementation some operations might not have the same characteristics of a regular thread-unsafe implementation.
-
Several F2084 Internal Error on Delphi 10.4.2
Stefan Glienke replied to Davide Angeli's topic in Delphi IDE and APIs
No, we are not - some individuals who also happen to be MVP are. -
Good quality Random number generator implementation
Stefan Glienke replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
https://xkcd.com/221/ -
LSP has nothing to do with that but the filter in the suggestion box. There were several plugins that could do that for ages.