Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3 type hints for performance optimizations

PEP 484 says "Using type hints for performance optimizations is left as an exercise for the reader." This suggests to me that, like Common Lisp, type declarations can be used to set aside type dispatch inside performance-intensive functions when I swear I know what I'm doing. To try this out for myself, I whipped up a little benchmark to calculate pi using a p-series. First I do it the naive way, then I try to be clever and exploit the type hints for performance:

import math
import time

def baselpi0(n):
    baselsum = 0;
    for i in range(1,n):
        baselsum += 1.0 / (i * i)
    return math.sqrt(6.0 * baselsum)

def baselpi1(n : int) -> float:
    n = float(n)
    baselsum  = 0.0
    i = 1.0
    while i < n:
        baselsum += 1.0 / (i * i)
        i += 1.0
    return math.sqrt(6.0 * baselsum)

start = time.time()
print(baselpi0(1000000000))
end = time.time()
print(end - start)
start = time.time()
print(baselpi1(1000000000))
end = time.time()
print(end - start)

The Common Lisp analogy I'm trying to emulate is:

(defun baselpi0 (n)
  (let ((baselsum 0.0d0))
    (loop for i from 1 to n do
      (setf baselsum (+ baselsum (/ 1.0 (* i i)))))
    (sqrt (* 6 baselsum))))

(defun baselpi1 (n)
  (let ((baselsum 0.0d0)
        (n (coerce n 'double-float)))
    (declare (type double-float baselsum n)
         (optimize (speed 3) (safety 0) (debug 0)))
    (loop for i from 1.0d0 to n do
          (setf baselsum (+ baselsum (/ 1.0d0 (* i i)))))
    (sqrt (* 6.0d0 baselsum))))

(time (princ (baselpi0 1000000000)))
(time (princ (baselpi1 1000000000)))
(exit)

On my machine, the lisp version run with sbcl takes 22 seconds for the slow version and 4 seconds for the type-hinted version, same as C. CPython takes 162 seconds for the naive version and 141 for the type-hinted version. Pypy runs the non-type-hinted version in just under 5 seconds, but the library support isn't good enough for my project.

Is there a way I can improve my type hinted version to get performance closer to lisp or Pypy?

like image 626
Juanote Avatar asked Oct 23 '16 16:10

Juanote


People also ask

Do Python type hints improve performance?

Type hints work best in modern Pythons. Annotations were introduced in Python 3.0, and it's possible to use type comments in Python 2.7. Still, improvements like variable annotations and postponed evaluation of type hints mean that you'll have a better experience doing type checks using Python 3.6 or even Python 3.7.

Do type annotations make Python faster?

So in short: no, they will not cause any run-time effects, unless you explicitly make use of them.

Does Python enforce type hints?

The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc. This module provides runtime support for type hints. The most fundamental support consists of the types Any , Union , Callable , TypeVar , and Generic .

Can you specify types in Python?

Luckily, Python supports the concept of gradual typing. This means that you can gradually introduce types into your code. Code without type hints will be ignored by the static type checker. Therefore, you can start adding types to critical components, and continue as long as it adds value to you.

Should you use type hints for performance optimization?

Using type hints for performance optimizations is left as an exercise for the reader. It should also be emphasized that Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention.

What are the best performance optimization tools for Python?

There are many market-tested and popular Python Optimization tools that can be leveraged for truly bringing out the full potential of Python programming and reducing development time while improving the efficiency and accuracy of your Python projects. Here is a curated list of top 5 Python performance optimization tools you can use: 1. DeepSource

How to solve optimization problem in Python?

Identifying the goal and constraints is the very first part of solving an optimization problem. Let’s resolve the optimization problem in Python. There are mainly three kinds of optimizations: It is the procedure of searching outcomes for the finest conceivable solution from a set of parameters.

What are type hints in Python?

Source code: Lib/typing.py The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc. This module provides runtime support for type hints. The most fundamental support consists of the types Any, Union, Callable , TypeVar, and Generic.


1 Answers

The speed difference is not due to type-hinting. Python currently, and for the foreseeable future, just discards any hints you offer and continues executing dynamically as it always does.

It's due to the fact that in one case you use floating arithmetic throughout the code (which results in faster execution) while in the other case you don't.

Case in point: Change baselpi1 to the following:

def baselpi1(n : int) -> float:
    n = float(n)
    baselsum  = 0
    i = 1
    while i < n:
        baselsum += 1.0 / (i * i)
        i += 1
    return math.sqrt(6.0 * baselsum)

And take a look at the execution times now:

3.141591698659554
0.2511475086212158
3.141591698659554
0.4525010585784912

Yes, it is way slower.

like image 103
Dimitris Fasarakis Hilliard Avatar answered Oct 17 '22 06:10

Dimitris Fasarakis Hilliard