Introduction to Pyrex September 2002 Brian Quinlan [email protected].
-
Upload
barnard-lindsey -
Category
Documents
-
view
219 -
download
1
Transcript of Introduction to Pyrex September 2002 Brian Quinlan [email protected].
![Page 2: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/2.jpg)
Slide 2 ©2002 Brian Quinlan
What is Pyrex?
• Pyrex is a language for writing Python extension modules
• Pyrex has a Python-like syntax that gets compiled into C code
• Pyrex let’s you mix Python and C data types and function calls freely
![Page 3: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/3.jpg)
Slide 3 ©2002 Brian Quinlan
The perfect example
• Let’s compute perfect numbers!
• Perfect numbers are number whose positive divisors (except for itself) sum to itself
e.g. 6 is a perfect number because:
1 x 6 = 6
2 x 3 = 6
1 + 2 + 3 = 6
• Naïve methods of computing perfect numbers are slow – so let’s use one and optimize
![Page 4: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/4.jpg)
Slide 4 ©2002 Brian Quinlan
The Python code
from math import sqrt, ceil
from operator import add
def _calculate_factors(x):
factors = [1]
sqrt_x = int(ceil(sqrt(x)))
for i in xrange(2, sqrt_x):
if x % i == 0:
factors.append(i)
factors.append(x / i)
if sqrt_x ** 2 == x: factors.append(sqrt_x)
return factors
def is_perfect(x):
return reduce(add, _calculate_factors(x), 0) == x
![Page 5: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/5.jpg)
Slide 5 ©2002 Brian Quinlan
The Pyrex code
from math import sqrt, ceil
from operator import add
def _calculate_factors(x):
factors = [1]
sqrt_x = int(ceil(sqrt(x)))
for i in xrange(2, sqrt_x):
if x % i == 0:
factors.append(i)
factors.append(x / i)
if sqrt_x ** 2 == x: factors.append(sqrt_x)
return factors
def is_perfect(x):
return reduce(add, _calculate_factors(x), 0) == x
![Page 6: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/6.jpg)
Slide 6 ©2002 Brian Quinlan
Pyrex is VERY like Python
• Pyrex syntax is VERY similar to Python syntax
• Running the same code using Pyrex is about 15% faster
• There are Pyrex-specific features that allow us to improve the performance even more
![Page 7: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/7.jpg)
Slide 7 ©2002 Brian Quinlan
Use C types
from math import sqrt, ceil
from operator import add
def _calculate_factors(int x):
cdef int sqrt_x, i
factors = [1]
sqrt_x = ceil(sqrt(x))
for i in xrange(2, sqrt_x):
if x % i == 0:
factors.append(i)
factors.append(x / i)
if sqrt_x ** 2 == x: factors.append(sqrt_x)
return factors
def is_perfect(int x):
return reduce(add, _calculate_factors(x), 0) == x
![Page 8: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/8.jpg)
Slide 8 ©2002 Brian Quinlan
Use a Pyrex “for” construct
from math import sqrt, ceil
from operator import add
def _calculate_factors(int x):
cdef int sqrt_x, i
factors = [1]
sqrt_x = ceil(sqrt(x))
for i from 2 <= i < sqrt_x:
if x % i == 0:
factors.append(i)
factors.append(x / i)
if sqrt_x ** 2 == x: factors.append(sqrt_x)
return factors
def is_perfect(int x):
return reduce(add, _calculate_factors(x), 0) == x
![Page 9: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/9.jpg)
Slide 9 ©2002 Brian Quinlan
Use the C math library
cdef extern from "math.h":
double sqrt(double x)
double ceil(double x)
from operator import add
def _calculate_factors(int x):
cdef int sqrt_x, i
factors = [1]
sqrt_x = ceil(sqrt(x))
for i from 2 <= i < sqrt_x:
if x % i == 0:
factors.append(i)
factors.append(x / i)
…
![Page 10: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/10.jpg)
Slide 10 ©2002 Brian Quinlan
Use C functions
cdef extern from "math.h":
…
from operator import add
cdef object _calculate_factors(int x):
cdef int sqrt_x, i
factors = [1]
sqrt_x = ceil(sqrt(x))
for i from 2 <= i < sqrt_x:
if x % i == 0:
factors.append(i)
factors.append(x / i)
if sqrt_x ** 2 == x: factors.append(sqrt_x)
return factors
…
![Page 11: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/11.jpg)
Slide 11 ©2002 Brian Quinlan
Do our own summation
…
def is_perfect(int x):
cdef int sum
cdef int i
sum = 0
for i in _calculate_factors(x):
sum = sum + i
return sum == x
![Page 12: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/12.jpg)
Slide 12 ©2002 Brian Quinlan
Results
6.81
5.96
3.58
2.21.92 1.79
1.38
0
1
2
3
4
5
6
7
Time(s)
Pyt
ho
n
Pyr
ex
+ cd
efs
+ fo
r
+ m
ath
+ fu
nc
+ su
m
![Page 13: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/13.jpg)
Slide 13 ©2002 Brian Quinlan
A vector class
cdef class Vector3:
cdef double x
cdef double y
cdef double z
def __init__(self, double x, double y, double z):
self.x, self.y, self.z = x, y, z
![Page 14: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/14.jpg)
Slide 14 ©2002 Brian Quinlan
Getting it’s attributes
def __getattr__(self, name):
if name == 'x':
return self.x
elif name == 'y':
return self.y
elif name == 'z':
return self.z
else:
raise AttributeError(
'Vector3 has no attribute "%s"' % name
)
![Page 15: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/15.jpg)
Slide 15 ©2002 Brian Quinlan
Some operations
def __add__(Vector3 a, Vector3 b):
return Vector3(a.x + b.x, a.y + b.y, a.z + b.z)
cdef int __nonzero__(Vector3 self):
return self.x or self.y or self.z
def __str__(self):
return 'Vector3(x=%s, y=%s, z=%s)' % (
self.x, self.y, self.z)
def __repr__(self): # __repr__ = __str__ not allowed
return 'Vector3(x=%r, y=%r, z=%r)' % (
self.x, self.y, self.z)
![Page 16: Introduction to Pyrex September 2002 Brian Quinlan brian@sweetapp.com.](https://reader036.fdocuments.us/reader036/viewer/2022082422/56649ea35503460f94ba7288/html5/thumbnails/16.jpg)
Slide 16 ©2002 Brian Quinlan
Using Pyrex
• The hassle-factor is low (easy to install Pyrex, easy to get Pyrex to compile your code - so long as you have a C compiler)
• Documentation is minimal but understandable
• Writing simple functions using Pyrex features is easy (though there are a few gotchas)
• Writing classes is harder (more gotches, more bugs, more unfinished features)
• C and the Python C API has more gotches than Pyrex