Today and this weekend aside, because things have turned for the worse temperature-wise, it's been a lovely week. As punishment for wishing for spring, I have been afflicted with an irritated nose, runny eyes, and itchy throat.

But in spite of setbacks--including spending Wednesday in a Benadryl coma--I've managed to wrap up, for now, the optimization work that began last week. Dream Seeker should have improved performance in several categories.
  • Another path for optimization was found in the view code, which also means the server side gets a slight benefit as well.
  • The gathering of view matrix parameters (opacity, etc.) has been sped up slightly, on the client only, by combining all atoms on a tile into the same routine and therefore avoiding redundant lookups.
  • Areas now cache their icon list for the duration of a tick; since the same area is usually called on to produce icons a few hundred times or more every tick, this is a non-trivial time savings.
  • Overall atom-to-icons production time has been trimmed as much as possible--which wasn't very much, but still there were a few minor improvements.
  • The tile-to-atom-list routine was improved by shortcutting a lot of redundant logic.
  • Sorting time for the master icon list has been cut in half. This isn't a big deal for small views, but for wider views it makes a bit of difference and in isometric--which currently sorts twice--it's huge.

    I have identified some targets for future optimizations, but it's time to put the mini-project to bed and move on to other items. In the future, this is what I'd like to target:

  • Transforms and color matrices use up a lot of memory in at least one of the icon formats, and also use a lot of extra logic in some others. It would be nice to switch to using shared items that just have a reference ID, which can later be garbage-collected as needed. This would generally save time as well as memory.
  • Items marked "interesting" by the server for the possibility of spreading out onto other tiles may not actually be visible within the map bounds. Since the client doesn't know this in advance, it still does atom-to-icons generation that ought to be skipped. Setting up some kind of crude visual bounds system on the client, like the server has already, would be a good idea.
  • Icons very much need to mark their physical positions--the webclient does this already--for the sake of future topological sort algorithms.
  • A lot of logic that handles changes of icon position due to client.dir should be completely changed to avoid even bothering with said logic until the main icon-filling loop is finished, since most projects never touch client.dir.

    But for now, time to move on back to hopefully getting the webclient in shape and also adding that client profiling that's been much requested. The groundwork for said profiling is already in place, in that there are places in the code where performance on these various rendering sub-tasks can be measured, so it's just a matter of adding to the frontend.

    Big thanks to everyone who's become a BYOND Member or donated, and those who've opted to show their support on Patreon. I know some power users in particular have been dying for a boost to performance, so I hope this latest round of optimizations works out well for you guys.
A minor addendum. I mentioned on my Patreon post that I was curious about extending the concept I used for improving sorts to several of the Bag classes used in BYOND for things like Appearances, etc. Over the weekend I modified the Appearance and AppearanceFilter bags to use a new form that avoids virtual functions entirely.

I also altered the way new ID arrays are added--which involved an O(N) search of existing ID arrays to find matches. Now they too use this new form of bag, which will allow for binary searches. This last bit means overlay list manipulation, since overlays and underlays are ID arrays internally, should be faster in projects that have a large number of ID arrays. Those arrays are also used for filters, proc code, and a bunch of other things.

There are a few other spots in the code where I could switch from the current qsort() calls to the new sort I implemented on the client, but they're not critical right now.
Thanks for all the hard work, Lummox. These improvements have seriously helped our project a lot.