Gaurav's Blog

return rand();

Profiling in Python

| Comments

I was trying to implement the Miller-Rabin algorithm for one of my home-works, in Python. I had already done this in C++ to solve PON, but I wanted to try out Python, and see how fast I can get it to. I wrote a function to do $a\^b$ mod $n $ which used repeated squaring to get the result. However, the implementation wasn’t fast enough. Dhruv suggested that I profile the code.

Here is how you profile a python script: python -m cProfile script.py

And this is what I came to know

1
2
3
4
5
6
7
8
9
10
11
12
13
14
172 function calls (66 primitive calls) in 31.492 seconds
    
       Ordered by: standard name
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
            1    0.000    0.000    0.000    0.000 __future__.py:48(<module>)
            1    0.000    0.000    0.000    0.000 __future__.py:74(_Feature)
            7    0.000    0.000    0.000    0.000 __future__.py:75(__init__)
            1    0.020    0.020    0.020    0.020 hashlib.py:55(<module>)
            6    0.000    0.000    0.000    0.000 hashlib.py:94(__get_openssl_constructor)
            1    0.063    0.063   31.492   31.492 millerRabin.py:1(<module>)
        108/2   16.644    0.154   16.644    8.322 millerRabin.py:12(fastModularExp)
            2    0.008    0.004   16.672    8.336 millerRabin.py:21(millerRabin)
            1    0.000    0.000    0.000    0.000 os.py:743(urandom)

Note how the fastModularExp() function took a staggering 16 seconds. Now we came to know that the builtin pow function in Python already does fast modular exponentiation. And since it is a part of a C library, it is quite fast. After doing this, I submitted it as a solution for PON and got accepted with 0.35 seconds, which was faster than my 0.90 submission with C++ :-)

Comments