Profiling IronPython

A High Performance Timer

Timing the World

 

 

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.

from System import DateTime

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:

from System.Diagnostics import Stopwatch

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. Smile

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 :

from HighPerformanceTimer.Kernel32 import (
    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. Smile

For buying techie books, science fiction, computer hardware or the latest gadgets: visit The Voidspace Amazon Store.

Hosted by Webfaction

Return to Top

Page rendered with rest2web the Site Builder

Last edited Fri Nov 27 18:32:35 2009.

Counter...