{"id":580,"date":"2009-06-21T23:41:45","date_gmt":"2009-06-21T13:41:45","guid":{"rendered":"http:\/\/www.vectorstorm.org\/?p=580"},"modified":"2009-06-21T23:42:10","modified_gmt":"2009-06-21T13:42:10","slug":"on-optimisations","status":"publish","type":"post","link":"https:\/\/www.vectorstorm.com.au\/2009\/06\/21\/on-optimisations\/","title":{"rendered":"On Optimisations"},"content":{"rendered":"

There’s an old maxim amongst programmers, that premature optimisation is the root of all evil. \u00a0Or to put that in a less glib way, it’s generally a bad idea to perform optimisations before your program is completed, and it’s always a bad idea to perform optimisations if you have no way to check your performance before and after. \u00a0In practice, this means that you need to use a profiler before you start thinking about performing optimisations.<\/p>\n

So apologies,\u00a0but it’s another technical post. \u00a0For those who aren’t interested in programmer topics but are looking for pretty screenshots or discussions about game design, please feel free to skip this one. \u00a0Coders, hit the ‘Continue Reading’, below. \u00a0:)<\/p>\n

<\/p>\n

There are several different types of profiler; \u00a0some need to be built into your program, some are external applications; \u00a0there are many different types, which are useful for different things. \u00a0Under OS X (which is where I’m currently doing my active development), there’s a free standalone profiler called “Shark”. \u00a0“Shark” is a statistical profiler, which means that it stops your program hundreds or thousands times per second, and checks to see what your program is doing at each of those points in time. \u00a0Based upon statistical analyses of the data it obtains, it can figure out which bits of your program seem to be taking the longest to run.<\/p>\n

There are two things which have been annoying me about MMORPG Tycoon 2 recently; \u00a0one is how long it takes for the program to build the world when it starts up (after it opens its window, it takes about five seconds on my laptop before it’s ready to render the world), and the other is how long it takes to shut the game down (quitting takes about two and a half seconds).<\/p>\n

For fun, I ran Shark over MMORPG Tycoon today, just to see why these two things were taking so long. \u00a0In the current builds, the world terrain is being built using some simple Perlin noise<\/a>. \u00a0While the noise is simple, it’s actually quite expensive to calculate so much of it. \u00a0I won’t be using Perlin noise for much longer, so I was curious to see just how much speed I was going to recover when I stopped using all that complex math. \u00a0I was also concerned about how long it must be taking to create and set up the terrain quad trees.<\/p>\n

As it turned out, though the Perlin noise and the quad trees weren’t very expensive at all. \u00a0In fact, there were two major culprits. \u00a0The profiler pointed out a really slow piece of code in the model building process; \u00a0I had a slow ‘for’ loop copying data from one place to another. \u00a0Replacing it with a simple memcpy() fixed that one. \u00a0The other culprit was repeatedly re-generating the same pieces of data during the world building process, instead of using data I’d already calculated. \u00a0I re-architected the world building to reuse the data which it had already calculated, and that sped things up even more. \u00a0The Perlin noise is still definitely slow, but fixing these two other issues brought down the startup time from 5 seconds to about 1.5 seconds. \u00a0I’m much happier with that speed! \u00a0I had also expected that building terrain quadtrees was going to be a major expense, but it turned out to be extremely minor.<\/p>\n

For the shutdown, it turned out that all the time being taken was occurring inside my memory management system (which is what I’d been half-expecting). \u00a0What I hadn’t expected to find was actually what was the particular operation that was using up so much time. \u00a0The problem was that the VectorStorm engine’s memory management was doing some extensive error checking on each block when it was freed; \u00a0making absolutely sure that the engine knew about the block of memory being deallocated before touching it in any way. \u00a0While that’s nice for testing purposes, it was really a bit overboard; \u00a0removing the silliest of the sanity checking brought the game’s shutdown time down from about two seconds to almost instantaneous.<\/p>\n

Moral of the story: \u00a0Profile your code before you decide what needs to be sped up. \u00a0If I’d just jumped in and started changing the things which I’d assumed were slow, I would never have found several of the big culprits; \u00a0they were tiny little things which I’d written many, many months ago; \u00a0not the things which actually sounded complicated and slow.<\/p>\n","protected":false},"excerpt":{"rendered":"

There’s an old maxim amongst programmers, that premature optimisation is the root of all evil. \u00a0Or to put that in a less glib way, it’s generally a bad idea to perform optimisations before your program is completed, and it’s always a bad idea to perform optimisations if you have no way to check your performance…<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":""},"categories":[4,25,3],"tags":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/po9WK-9m","_links":{"self":[{"href":"https:\/\/www.vectorstorm.com.au\/wp-json\/wp\/v2\/posts\/580"}],"collection":[{"href":"https:\/\/www.vectorstorm.com.au\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vectorstorm.com.au\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vectorstorm.com.au\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vectorstorm.com.au\/wp-json\/wp\/v2\/comments?post=580"}],"version-history":[{"count":0,"href":"https:\/\/www.vectorstorm.com.au\/wp-json\/wp\/v2\/posts\/580\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.vectorstorm.com.au\/wp-json\/wp\/v2\/media?parent=580"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vectorstorm.com.au\/wp-json\/wp\/v2\/categories?post=580"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vectorstorm.com.au\/wp-json\/wp\/v2\/tags?post=580"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}