File: functional.py

package info (click to toggle)
python-scipy 0.18.1-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 75,464 kB
  • ctags: 79,406
  • sloc: python: 143,495; cpp: 89,357; fortran: 81,650; ansic: 79,778; makefile: 364; sh: 265
file content (104 lines) | stat: -rw-r--r-- 2,878 bytes parent folder | download | duplicates (2)
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
#       C:\home\eric\wrk\scipy\weave\examples>python functional.py
#       desired: [2, 3, 4]
#       actual: [2, 3, 4]
#       actual2: [2, 3, 4]
#       python speed: 0.039999961853
#       SCXX speed: 0.0599999427795
#       speed up: 0.666666666667
#       c speed: 0.0200001001358
#       speed up: 1.99998807913
from __future__ import absolute_import, print_function

import sys
sys.path.insert(0,'..')
import inline_tools
from types import *


def c_list_map(func,seq):
    """ Uses CXX C code to implement a simple map-like function.
        It does not provide any error checking.
    """
    assert(type(func) in [FunctionType,MethodType,type(len)])
    code = """
           #line 22 "functional.py"
           py::tuple args(1);
           int N = seq.len();
           py::list result(N);
           for(int i = 0; i < N;i++)
           {
              args[0] = seq[i];
              result[i] = func.call(args);
           }
           return_val = result;
           """
    return inline_tools.inline(code,['func','seq'])


def c_list_map2(func,seq):
    """ Uses Python API more than CXX to implement a simple map-like function.
        It does not provide any error checking.
    """
    assert(type(func) in [FunctionType,MethodType,type(len)])
    code = """
           #line 40 "functional.py"
           py::tuple args(1);
           PyObject* py_args = (PyObject*)args;
           py::list result(seq.len());
           PyObject* py_result = (PyObject*)result;
           PyObject* item = NULL;
           PyObject* this_result = NULL;
           int N = seq.len();
           for(int i = 0; i < N;i++)
           {
              item = PyList_GET_ITEM(py_seq,i);
              Py_INCREF(item);
              PyTuple_SetItem(py_args,0,item);
              this_result = PyEval_CallObject(py_func,py_args);
              PyList_SetItem(py_result,i,this_result);
           }
           return_val = result;
           """
    return inline_tools.inline(code,['func','seq'])


def main():
    seq = ['aa','bbb','cccc']
    print('desired:', map(len,seq))
    print('actual:', c_list_map(len,seq))
    print('actual2:', c_list_map2(len,seq))


def time_it(m,n):
    import time
    seq = ['aadasdf'] * n
    t1 = time.time()
    for i in range(m):
        result = map(len,seq)
    t2 = time.time()
    py = t2 - t1
    print('python speed:', py)

    #load cache
    result = c_list_map(len,seq)
    t1 = time.time()
    for i in range(m):
        result = c_list_map(len,seq)
    t2 = time.time()
    c = t2-t1
    print('SCXX speed:', c)
    print('speed up:', py / c)

    #load cache
    result = c_list_map2(len,seq)
    t1 = time.time()
    for i in range(m):
        result = c_list_map2(len,seq)
    t2 = time.time()
    c = t2-t1
    print('c speed:', c)
    print('speed up:', py / c)

if __name__ == "__main__":
    main()
    time_it(100,1000)