Construct BuiltinSumWithGenerator

Performance Diagrams

Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)20281876988.11538461538461257.0CPython 2.7126658856240.03846153846155349.793612179301Nuitka (master)126664148391.96153846153845349.78716438050094Nuitka (develop)126659897543.8846153846154349.7923438197864Nuitka (factory)Construct BuiltinSumWithGeneratorTicks Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000280000000280000000300000000300000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)30208132688.11538461538461257.0CPython 3.5173182244240.03846153846155362.4449364572771Nuitka (master)173182119391.96153846153845362.4450387125985Nuitka (develop)173182726543.8846153846154362.4445421607578Nuitka (factory)Construct BuiltinSumWithGeneratorTicks

Source Code with Construct

empty = ()

def calledRepeatedly():
    # We measure making a generator iterator step or not.
    gen = (x for x in range(1000))

    # This should abort.
# construct_begin
    y = sum(gen)
# construct_alternative



    return y, gen

import itertools
for x in itertools.repeat(None, 500):
    calledRepeatedly()

print("OK.")

Source Code without Construct

empty = ()

def calledRepeatedly():
    # We measure making a generator iterator step or not.
    gen = (x for x in range(1000))

    # This should abort.
# construct_begin

# construct_alternative
    y = gen
# construct_end

    return y, gen

import itertools
for x in itertools.repeat(None, 500):
    calledRepeatedly()

print("OK.")

Context Diff of Source Code


Construct
Baseline
24     # We measure making a generator iterator step or not. 24     # We measure making a generator iterator step or not.
25     gen = (x for x in range(1000)) 25     gen = (x for x in range(1000))
26 26
27     # This should abort. 27     # This should abort.
28 # construct_begin 28 # construct_begin
n 29     y = sum(gen) n 29  
30 # construct_alternative 30 # construct_alternative
t 31   t 31     y = gen
32   32 # construct_end
33 33
34     return y, gen 34     return y, gen
35 35
36 import itertools 36 import itertools
37 for x in itertools.repeat(None, 500): 37 for x in itertools.repeat(None, 500):

Context Diff of Generated Code


Construct
Baseline
145 145
146     // Local variable declarations. 146     // Local variable declarations.
147     PyObject *var_y = NULL; 147     PyObject *var_y = NULL;
148     PyObject *var_gen = NULL; 148     PyObject *var_gen = NULL;
149     PyObject *tmp_genexpr_1__$0 = NULL; 149     PyObject *tmp_genexpr_1__$0 = NULL;
n 150     struct Nuitka_FrameObject *frame_896e5b5b52e209d10b16aca255f0ea24; n
151     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
152     PyObject *exception_type = NULL;
153     PyObject *exception_value = NULL;
154     PyTracebackObject *exception_tb = NULL;
155     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
156     static struct Nuitka_FrameObject *cache_frame_896e5b5b52e209d10b16aca255f0ea24 = NULL;
157     PyObject *tmp_return_value = NULL; 150     PyObject *tmp_return_value = NULL;
n 158     PyObject *exception_keeper_type_1; n
159     PyObject *exception_keeper_value_1;
160     PyTracebackObject *exception_keeper_tb_1;
161     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
162 151
163     // Actual function body. 152     // Actual function body.
164     { 153     {
165         PyObject *tmp_assign_source_1; 154         PyObject *tmp_assign_source_1;
166         { 155         {
199         return NULL; 188         return NULL;
200         outline_result_1:; 189         outline_result_1:;
201         assert(var_gen == NULL); 190         assert(var_gen == NULL);
202         var_gen = tmp_assign_source_1; 191         var_gen = tmp_assign_source_1;
203     } 192     }
n n 193     {
194         PyObject *tmp_assign_source_3;
195         CHECK_OBJECT(var_gen);
196         tmp_assign_source_3 = var_gen;
197         assert(var_y == NULL);
198         Py_INCREF(tmp_assign_source_3);
199         var_y = tmp_assign_source_3;
200     }
204     // Tried code: 201     // Tried code:
n 205     MAKE_OR_REUSE_FRAME(cache_frame_896e5b5b52e209d10b16aca255f0ea24, codeobj_896e5b5b52e209d10b16aca255f0ea24, module___main__, sizeof(void *)+sizeof(void *)); n
206     frame_896e5b5b52e209d10b16aca255f0ea24 = cache_frame_896e5b5b52e209d10b16aca255f0ea24;
207  
208     // Push the new frame as the currently active one.
209     pushFrameStack(frame_896e5b5b52e209d10b16aca255f0ea24);
210  
211     // Mark the frame object as in use, ref count 1 will be up for reuse.
212     assert(Py_REFCNT(frame_896e5b5b52e209d10b16aca255f0ea24) == 2); // Frame stack
213  
214     // Framed code:
215     {
216         PyObject *tmp_assign_source_3;
217         PyObject *tmp_sum_sequence_1;
218         CHECK_OBJECT(var_gen);
219         tmp_sum_sequence_1 = var_gen;
220         tmp_assign_source_3 = BUILTIN_SUM1(tmp_sum_sequence_1);
221         if (tmp_assign_source_3 == NULL) {
222             assert(ERROR_OCCURRED());
223  
224             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
225  
226  
227             exception_lineno = 29;
228             type_description_1 = "oo";
229             goto frame_exception_exit_1;
230         }
231         assert(var_y == NULL);
232         var_y = tmp_assign_source_3;
233     }
234  
235 #if 0
236     RESTORE_FRAME_EXCEPTION(frame_896e5b5b52e209d10b16aca255f0ea24);
237 #endif
238  
239     // Put the previous frame back on top.
240     popFrameStack();
241  
242     goto frame_no_exception_1;
243  
244     frame_exception_exit_1:;
245  
246 #if 0
247     RESTORE_FRAME_EXCEPTION(frame_896e5b5b52e209d10b16aca255f0ea24);
248 #endif
249  
250     if (exception_tb == NULL) {
251         exception_tb = MAKE_TRACEBACK(frame_896e5b5b52e209d10b16aca255f0ea24, exception_lineno);
252     }
253     else if (exception_tb->tb_frame != &frame_896e5b5b52e209d10b16aca255f0ea24->m_frame) {
254         exception_tb = ADD_TRACEBACK(exception_tb, frame_896e5b5b52e209d10b16aca255f0ea24, exception_lineno);
255     }
256  
257     // Attachs locals to frame if any.
258     Nuitka_Frame_AttachLocals(
259         (struct Nuitka_FrameObject *)frame_896e5b5b52e209d10b16aca255f0ea24,
260         type_description_1,
261         var_y,
262         var_gen
263     );
264  
265  
266     // Release cached frame.
267     if (frame_896e5b5b52e209d10b16aca255f0ea24 == cache_frame_896e5b5b52e209d10b16aca255f0ea24) {
268         Py_DECREF(frame_896e5b5b52e209d10b16aca255f0ea24);
269     }
270     cache_frame_896e5b5b52e209d10b16aca255f0ea24 = NULL;
271  
272     assertFrameObject(frame_896e5b5b52e209d10b16aca255f0ea24);
273  
274     // Put the previous frame back on top.
275     popFrameStack();
276  
277     // Return the error.
278     goto try_except_handler_2;
279  
280     frame_no_exception_1:;
281     { 202     {
282         PyObject *tmp_tuple_element_1; 203         PyObject *tmp_tuple_element_1;
283         CHECK_OBJECT(var_y); 204         CHECK_OBJECT(var_y);
284         tmp_tuple_element_1 = var_y; 205         tmp_tuple_element_1 = var_y;
285         tmp_return_value = PyTuple_New(2); 206         tmp_return_value = PyTuple_New(2);
303     CHECK_OBJECT((PyObject *)var_gen); 224     CHECK_OBJECT((PyObject *)var_gen);
304     Py_DECREF(var_gen); 225     Py_DECREF(var_gen);
305     var_gen = NULL; 226     var_gen = NULL;
306 227
307     goto function_return_exit; 228     goto function_return_exit;
n 308     // Exception handler code: n
309     try_except_handler_2:;
310     exception_keeper_type_1 = exception_type;
311     exception_keeper_value_1 = exception_value;
312     exception_keeper_tb_1 = exception_tb;
313     exception_keeper_lineno_1 = exception_lineno;
314     exception_type = NULL;
315     exception_value = NULL;
316     exception_tb = NULL;
317     exception_lineno = 0;
318  
319     CHECK_OBJECT((PyObject *)var_gen);
320     Py_DECREF(var_gen);
321     var_gen = NULL;
322  
323     // Re-raise.
324     exception_type = exception_keeper_type_1;
325     exception_value = exception_keeper_value_1;
326     exception_tb = exception_keeper_tb_1;
327     exception_lineno = exception_keeper_lineno_1;
328  
329     goto function_exception_exit;
330     // End of try: 229     // End of try:
331 230
332     // Return statement must have exited already. 231     // Return statement must have exited already.
333     NUITKA_CANNOT_GET_HERE(__main__$$$function_1_calledRepeatedly); 232     NUITKA_CANNOT_GET_HERE(__main__$$$function_1_calledRepeatedly);
334     return NULL; 233     return NULL;
335 234
t 336 function_exception_exit: t
337     assert(exception_type);
338     RESTORE_ERROR_OCCURRED(exception_type, exception_value, exception_tb);
339  
340     return NULL;
341 235
342 function_return_exit: 236 function_return_exit:
343    // Function cleanup code if any. 237    // Function cleanup code if any.
344 238
345 239