brentp (owner)

Revisions

gist: 95916 Download_button fork
public
Public Clone URL: git://gist.github.com/95916.git
Embed All Files: show embed
Python #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# interval_new.pyx
cpdef class Interval:
    cdef public int start
    cdef public int end
 
    def __init__(self, start, end):
        self.start = start
        self.end = end
 
cdef extern from "pnew.h":
    cdef Interval NEW_INTERVAL "PY_NEW" (object t)
 
 
cpdef create_interval(int start, int end):
    cdef Interval iv = NEW_INTERVAL(Interval)
    iv.start = start
    iv.end = end
    return iv
 
def batch_create(interval_list):
    return [create_interval(start, end) for start, end
            in interval_list]
 
def batch_init(interval_list):
    return [Interval(start, end) for start, end
            in interval_list]
 
#-------------------------------------------------------------------------------------------#
# pnew.h
#define PY_NEW(T) \
     (((PyTypeObject*)(T))->tp_new( \
             (PyTypeObject*)(T), __pyx_empty_tuple, NULL))
#-------------------------------------------------------------------------------------------#
# setup.py -- run with python setup.py build_ext --inplace
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup( name = 'interval_new'
        , ext_modules=[ Extension("interval_new", sources=["interval_new.pyx"]
           )]
        , cmdclass = {'build_ext': build_ext}
  )
 
#-------------------------------------------------------------------------------------------#
# t.py (run timings)
from interval_new import create_interval, batch_create, Interval, batch_init
import time
 
N = range(2000000)
 
class PyInterval(object):
    def __init__(self, start, end):
        self.start = start
        self.end = end
 
class PySlotsInterval(PyInterval):
    __slots__ = ('start', 'end')
 
 
t0 = time.time()
[create_interval(100, 200) for i in N]
print "PY_NEW on Cython class: %.3f" % (time.time() - t0)
 
 
 
t0 = time.time()
[PyInterval(100, 200) for i in N]
print "__init__ on Python class: %.3f" % (time.time() - t0)
 
 
t0 = time.time()
[PySlotsInterval(100, 200) for i in N]
print "__init__ on Python class with slots: %.3f" % (time.time() - t0)
 
 
t0 = time.time()
start_stops = [(100, 200) for i in N]
t1 = time.time()
batch_create(start_stops)
t2 = time.time()
print "batch PY_NEW total: %.3f" % (t2 - t0),\
        ", interval only: %.3f" % (t2 - t1)
 
 
t0 = time.time()
start_stops = [(100, 200) for i in N]
t1 = time.time()
batch_init(start_stops)
t2 = time.time()
print "batch __init__ on Cython class total %.3f" % (t2 - t0),\
        ", interval_only: %.3f" % (t2 - t1)
 
t0 = time.time()
[Interval(100, 200) for i in N]
print "__init__ on Cython class %.3f" % (time.time() - t0)
 
 
 
#-------------------------------------------------------------------------------------------#
# TIMING output:
 
PY_NEW on Cython class: 1.137
__init__ on Python class: 28.468
__init__ on Python class with slots: 9.936
batch PY_NEW total: 0.821 , interval only: 0.363
batch __init__ on Cython class total 0.975 , interval_only: 0.524
__init__ on Cython class 1.154