Медленнее в 10 раз / 10 times slower

Решил переписать программу по работе на основании новых знаний и умений. Интересное наблюдение: переписал загрузку данных через Generics.Collections  и TObjectDictionary. В результате загрузка с 4 секунд превратилась в … 50 секунд. Не смешно. Ладно, данные обрабатываются теперь лучше, но сама работа с объектами – это провал для производительности… эх… можно было бы без них обойтись…

Зато при этом сортировка – более чем в 25 раз быстрее в дженериках 🙂

I’ve decided to rewrite a program I needed for work based on my new knowledge and skills. An interesting observation: I’ve rewritten data loading through Generics.Collections and TObjectDictionary. And as a result the loading time changed from 4 seconds into … 50 seconds. Not funny at all. Ok, the data is processed better, but working with objects is a blackhole of efficiency… eh… I wish it’d be possible to do everything without OOP…

And with all this even simple search/sorting is over 25 times faster for generics.

Медленнее в 10 раз / 10 times slower

2 thoughts on “Медленнее в 10 раз / 10 times slower

  1. I think that saying “working with objects is a blackhole of efficiency”, and suggesting that OOP is inherently slow, is a bit too broad 🙂

    I would investigate what is causing the slowness in your particular case. How did the data layout / access methods change between your old code, and the new code using “Generics.Collections”.

    Note that you can use simple primitive types (Integers, booleans), or records, with TDictionary. “Generics.Collections” is not forcing you to wrap your data in classes. Neither does TObjectDictionary — even in TObjectDictionary, keys or values may be simple types / records. TObjectDictionary only adds a possibility to auto-free if keys and/or values happen to be object instances.

    If you find the memory layout of TDictionary / TObjectDictionary inefficient, you can also use simple lists (e.g. 1 list with key/value in a record). And implement the equivalent of “searching for key” on your own, using binary search or any other algorithm that is suitable in your case. In the simplest case, you would just put key and value in a record, and stuff it inside TList (or CGE TStructList). The internal structure of TList/TStructList is just a linear array of items, so it can be really efficient and cache-friendly if used with simple types or records.

    None of these advices are guaranteed to bring you back your original speed, of course 🙂 So I don’t suggest just doing them and trying if they help (I have many cases in CGE where the speed of TObjectDictionary or TObjectList is definitely not a bottleneck). But I advice investigating (measuring with a profiler, like Valgrind or your own 🙂 ) and pinpointing the problem.

    Liked by 1 person

  2. Well, let’s put it simple. With Generics.Collections I loose 46 seconds in loading and I win 21 minutes in sorting 750000 records and removing duplicates 🙂 Not mentioning much, much more convenient data processing (I need more advanced data processing methods which consider data errors this turn, I hardly can make that code readable with fixed-size arrays as I did before).
    So, yes, that was a relatively stupid conclusion caused by my irritation with Generics.Collections API and subsequent Assembler nostalgia 🙂


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s