summaryrefslogtreecommitdiff
path: root/weave/examples/functional.py
blob: cd907aec49abf870a52dd6ce0956443f5ef11840 (plain)
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
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 12 "functional.py"
           Py::Tuple args(1);    
           Py::List result(seq.length());
           PyObject* this_result = NULL;
           for(int i = 0; i < seq.length();i++)
           {
              args[0] = seq[i];
              this_result = PyEval_CallObject(func,args.ptr());
              result[i] = Py::Object(this_result);
           }           
           return_val = Py::new_reference_to(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 32 "functional.py"
           Py::Tuple args(1);    
           Py::List result(seq.length());
           PyObject* item = NULL;
           PyObject* this_result = NULL;
           for(int i = 0; i < seq.length();i++)
           {
              item = PyList_GET_ITEM(seq.ptr(),i);
              PyTuple_SetItem(args.ptr(),0,item);
              this_result = PyEval_CallObject(func,args.ptr());
              PyList_SetItem(result.ptr(),i,this_result);              
           }           
           return_val = Py::new_reference_to(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 'c 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)