Low level code optimization or "How I made Zoom Player's options dialog open faster"
Introduction
Over the years I've received justified complaints that the advanced options dialog takes too long to open, especially on older or weaker PCs.
Over the years
If you followed Zoom Player's change log, you would have noticed that I took several attempts to fix this issue, always being able to shave a few milliseconds here and there, but never really achieving a truly noticeable gain.
Diving in
This week I took another step forward. I mapped out the massive code that creates the options dialog and populates it with Zoom Player's current configuration state.
I then reviewed the log, trying to figure out which bits of code are taking the most time to complete. The first major issue I found was the way I was restoring the left-panel's tree-view to the previously viewed state. Apparently, I wasn't restoring it correctly, taking a 700ms performance hit. Changing the method I used to select the previously active tree node reduced this action to around 25ms, yay!
The ComboBox
I continued reviewing the code and hit another anomaly. For some reason, adding items to a ComboBox (drop-down list) component and then duplicating the items across 3 more components was taking 100ms. This didn't make sense; I had previously written code that adds 1000's of items to other components, and it took far less time.
Turns out the standard Windows ComboBox component is dog-shit slow when adding items. The underlying code uses WinAPI's SendMessage command for every item added, increasing the CPU overhead a hundred-fold.
Disappointment
Trying to find a solution, I discovered a few tips online which helped improve performance by approximately 200ms.
That's nice, I thought; let's benchmark the current v21 build versus v20.1 and see how far I progressed. I ran both builds and compared the results. The new build took an extra 50ms to open the options dialog 🤦♂️
You see, in version 21 I've added A LOT of new settings to the options dialog—so many that even after this optimization round, I basically reached parity with the previous version.
Death of a ComboBox
The tips to improve the ComboBox performance helped a bit, but were nowhere close to the speed of using a standard in-memory list (TStringList).
Replacing a system-level component such as the ComboBox is not simple. It might look easy on the surface, but there are a lot of behavioral/design patterns that must be duplicated to maintain a good user experience.
I decided to test if an AI is up to the task of creating a drop-in replacement for the ComboBox. I used OpenAI's o3-mini-high for this, and while this was quite a long process, taking many hours to iron out bugs, behavioral glitches, and lock in the visual design, I was eventually able to create a drop-in replacement for ComboBox, which I open-sourced.
Success
Even though Zoom Player has 100's of other components (text lists, edit boxes, check boxes, radio lists, etc.) being created when opening the options dialog, the ComboBox was by far the most dominant CPU hog. Replacing the ComboBox with a custom component gave me the serious performance boost I was looking for.
Here are the approximate numbers (based on my elderly PC):
v20.1 final - 2400ms
v21 beta 1 - 3200ms
v21 beta 2 - 1300ms
The actual numbers should be slightly faster. These numbers represent the debug version which is slightly slower in general.