Since Delphi got generic types, in the 2009 version, its runtime library (RTL) has a generic collections unit. The RTL however, still has the classic collections. Recently I got some requests about which is recommended to use, and while the discussion can go a bit deeper, I wanted to blog a high level overview.
The most basic collection class in the RTL is the TList class (in the System.Classes unit), which represents a general list of pointers (or object references). The container classes (in the System.Contnrs unit) includes the following:
When you are using these containers you often need to cast from the type of the objects you are managing to the fixed type the list supports. This introduced the possibility of errors and causes some runtime delay if you continuously check the type of the objects extracted from the list with dynamic casts (like "as"):
myList.Get(3) as TMyObject
Along with generic types in the language Delphi added a set of basic generic collections. These are defined in the System.Generics.Collections unit and offer a generic blueprint for containers tied to the specific data type you need. Generic collections include:
Generics collections offer the ability to define specific containers for given data types you need to use, and let the compiler check the data type compatibility, rather than doing the same at runtime. This results in cleaner and more readable code, more robust applications, and faster execution -- given the reduced need ot runtime checks:
myList: TList <TMyObject>;
myList.Get(3); // returns TMyObject
All of the new libraries and subsystems in Delphi use the new collections, for example FireMonkey leverages them a lot rather than using the traditional coding style.
There are basically two reasons for not using the new collections. One is that if you have existing working code, you might not want to change it. Even more if the code is in a library (like VCL) changing it could cause incompatibility in code that uses the library.
The other reason is that generics in Delphi cause a significant code bloat, because for any data type used by the collection the class methods are replicated, even if almost identical. In very large applications, this has a negative effect on compile and link time and on executable side.
Finally, I want to mention that if you use generic collections heavily, you should consider those available in the Spring4D library, which extends what we have in the RTL. See the documentation at https://bitbucket.org/sglienke/spring4d/wiki/Collections
Again this is meant to be a short summary and I know I could have been more extensive and precise, hope it is helpful to some of the old developers not fully aware of our generic collections -- which was the goal of the blog post.
Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder. Design. Code. Compile. Deploy.
Start Free Trial
Free Delphi Community Edition
Free C++Builder Community Edition
Yes, very interesting. I wonder if the performance comes to expense of size of binary -- there is often a trade off. I'll have a deeper look, thanks for the link
You should see this project:github.com/.../Rapid.Generics
Good blog; concise and useful. Questions: How significant is "significant code bloat?" Is there any quantifiable information about this? Also, how do generics impact Big O? The implication is they're more efficient.
Thanks for a good blog.
The generics are really useful. I am wondering what the word "significant" means ("significant code bloat") How much is that? Can you quantify the term? And how do generics impact Big O? Thanks for a good blog.
I don't quite understand what this article is about.