Profiling IronPython
A High Performance Timer

Contents
Profiling with IronPython
The first step in optimising any code is to profile and find out where the time is really being spent. As often as not this is in surprising places.
For profiling IronPython code you can use the .NET DateTime class.
start = DateTime.Now
someFunction()
timeTaken = (DateTime.Now - start).TotalMilliseconds
Note that you don't need to explicitly add a reference to the System assembly, IronPython already has one.
There is a drawback with the code above. DateTime has a granularity of about 15milliseconds. For timing individual calls to fairly quick code, this can be way too coarse.
Note
There is also a managed high performance timer class available from the .NET framework (new in .NET 2). This is the Stopwatch class.
You can use it with:
s = Stopwatch()
s.Start()
# Do some stuff
s.Stop()
timespan = s.Elapsed
print timespan.Milliseconds
An alternative is to use a high-resolution performance counter from kernel.dll. As you might expect, this has a much higher resolution.
This is in unmanaged code, so you need to expose it with some C#.
The following code uses the QueryPerformanceFrequency and the QueryPerformanceCounter
using System;
using System.Runtime.InteropServices;
namespace HighPerformanceTimer
{
public class Kernel32
{
[DllImport("kernel32.dll")]
public static extern bool QueryPerformanceCounter(out long performanceCount);
[DllImport("kernel32.dll")]
public static extern bool QueryPerformanceFrequency(out long frequency);
}
}
Compile it to a DLL. You can see C# and the Clipboard for an example of compiling C# using free tools.
Note
If you have an AMD multi-core CPU then it might be worth applying the following update:
http://support.microsoft.com/?id=896256
It's not part of Microsoft Update, and without it you can find that these timers occasionally return lower values for subsequent calls (but maybe travelling backwards in time is desirable)...
You can then create a 'Timer' module in IronPython which uses it :
QueryPerformanceCounter, QueryPerformanceFrequency
)
_, frequency = QueryPerformanceFrequency()
def Ticks():
_, time = QueryPerformanceCounter()
return time / float(frequency)
The Ticks function can be used in place of the DateTime code shown above. It returns time (as a floating point number) in seconds.
For buying techie books, science fiction, computer hardware or the latest gadgets: visit The Voidspace Amazon Store.
Last edited Fri Nov 27 18:32:35 2009.
Counter...

