The importance of profiling
We love to optmize code, all programmers do. We find joy and pleasure
in writing more optimal and faster algorithms and routines. The problem
is that most times, we just do it and think that the new code will be
better, without taking measures or doing some tests to confirm that the
new code is in fact faster than the old one.
Since the last
update, I´ve spent most of my time profiling Jade. While I´m not able
to make architectural changes to improve performance, I can find some
functions that are not well written and improve them. I´ve had a lot of
fun fighting with the Hashtable and Dictionary classes.
When I did my first profiles, I found two dark points:
- JEffectBuilder
- Building shadow volumes in the light pass
Both
parts were using a lot of time calling several methods of the Hashtable
class (Contains, [], Add,...). I started looking first at the
JEffectBuilder class. There the Hashtable was declared as:
Hashtable effects = new Hashtable;
I
browsed the code to search what it was using as keys and values: it was
using JUniqueEffectID (struct) for the keys and JEffect (a class) for
the values.
My first move was to change it to the Dictionary
class. I like a lot generics and generic collections (they save casts),
so a Dictionary should work better than a Hashtable. I also changed the
keys from JUniqueEffectID to int because that struct has a field called
Global that is like a hash value. It wasn´t going to save me from the
call to GetHashCode, but well, I felt it was more natural to put it
that way.
I profiled again the code and well, I was amazed: the
time used by the JEffectBuilder diminished a lot. I was very happy with
this, but I couldn´t believe that changing from Hashtable to Dictionary
would yield such a great speed improvement. I rushed to do the same
change in the shadow volumes, because they were well... slow as hell to
say the least.
I re-ran the profiler again, and I was shocked by
the results: the shadow volumes were as slow as usual. I started to
think what had happened, because I was really surprised that I had
changed the Hashtable of the shadow volumes to a Dictionary and the
speed was the same... And then I realized: the problem was in the
GetHashCode method. I don´t know the implementation, but I´m pretty
sure that calculating the hash code of a struct is a lot slower than
calculating the code of an int. That´s why changing to int keys from
structs gave me such a big improvement in speed in the JEffectBuilder
while in the shadow volumes, as the keys were already int values, I
didn´t notice the boost.
I then had another strange result:
Dictionaries have a method called TryGetValue. In the .NET 2.0
framework there are a lot of methods like that (like TryParse in float,
int, double,...) that help to make code faster and easier to read. In
Jade, the TryGetValue would save me from calling first Contains to see
if a key existed in the dictionary, and then using the indexer to get
the value. I was reducing the number of calls in half :)
I did
some test projects, and they confirmed my idea: using TryGetValue was
nearly 2 times faster than using Contains and the Indexer. But then the
strange thing happened: when implemented in Jade, it was slower :(
I
will continue studying this result, because it doesn´t make any sense
at all (or I haven´t found it yet). I must admit it can be also that I
haven´t run enough tests: my laptop heats quite fast when running Jade
and then the performance of my ATI card drops a lot. I´ll investigate
this one further.
Appart from my rambling in profiling and optimization, this last check in has several other aditions:
- documentation and translation fixes (seems they aren´t going to end any time soon).
-
a third person camera class written by gonzo. Very nice addition for
the default camera classes of Jade (and much more useful later in his
editor JadEd).
- fixed some error messages in the code: the engine
wasn´t reporting some errors as it should. Sweenie and timbann wrote
some code that fixes that.
- fixed the dammed resize bug: Haddd
found it at the end, after fighting with it since nearly the start of
the engine coding. This will help a lot in the work of the editor.
-
the old Haddd editor ported to Jade. Haddd and I ported it to the new
code so people can use it as a testbench for their own experiments.
Nothing
more I think, probably the next post will be about the new virtual file
system of Jade. Or maybe about a surprise, but I don´t know where it´ll
be ready (I´m not writting it ;)
Comments