Construct BuiltinSumWithGenerator

Performance Diagrams

Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000CPython 2.7Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)19085305072.9230769230769296.6373653873429CPython 2.70194.46153846153845504.11538461538464Nuitka (historic)227314320316.0257.0Nuitka (master)227313973437.53846153846143257.00037722673375Nuitka (develop)227310261559.0769230769231257.00441257438666Nuitka (factory)Construct BuiltinSumWithGeneratorTicks Construct BuiltinSumWithGenerator 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000280000000280000000300000000300000000CPython 3.5Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)30373519072.9230769230769257.0CPython 3.50194.46153846153845504.11538461538464Nuitka (historic)273233669316.0281.8156793859455Nuitka (master)273176891437.53846153846143281.8618733001498Nuitka (develop)272175222559.0769230769231282.67681943856826Nuitka (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

for x in xrange(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

for x in xrange(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 for x in xrange(500): 36 for x in xrange(500):
37     calledRepeatedly() 37     calledRepeatedly()

Context Diff of Generated Code


Construct
Baseline
139 #endif 139 #endif
140 140
141     // Local variable declarations. 141     // Local variable declarations.
142     PyObject *var_gen = NULL; 142     PyObject *var_gen = NULL;
143     PyObject *var_y = NULL; 143     PyObject *var_y = NULL;
n 144     PyObject *exception_type = NULL, *exception_value = NULL; n
145     PyTracebackObject *exception_tb = NULL;
146     NUITKA_MAY_BE_UNUSED int exception_lineno = -1;
147     PyObject *exception_keeper_type_1;
148     PyObject *exception_keeper_value_1;
149     PyTracebackObject *exception_keeper_tb_1;
150     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
151     PyObject *tmp_assign_source_1; 144     PyObject *tmp_assign_source_1;
152     PyObject *tmp_assign_source_2; 145     PyObject *tmp_assign_source_2;
153     PyObject *tmp_dircall_arg1_1; 146     PyObject *tmp_dircall_arg1_1;
154     PyObject *tmp_iter_arg_1; 147     PyObject *tmp_iter_arg_1;
155     PyObject *tmp_return_value; 148     PyObject *tmp_return_value;
n 156     PyObject *tmp_sum_sequence_1; n
157     PyObject *tmp_tuple_element_1; 149     PyObject *tmp_tuple_element_1;
n 158     static struct Nuitka_FrameObject *cache_frame_function = NULL; n
159  
160     struct Nuitka_FrameObject *frame_function;
161  
162     char const *type_description;
163     tmp_return_value = NULL; 150     tmp_return_value = NULL;
164 151
165     // Actual function code. 152     // Actual function code.
166     tmp_iter_arg_1 = const_xrange_0_1000; 153     tmp_iter_arg_1 = const_xrange_0_1000;
167     tmp_dircall_arg1_1 = MAKE_ITERATOR( tmp_iter_arg_1 ); 154     tmp_dircall_arg1_1 = MAKE_ITERATOR( tmp_iter_arg_1 );
173     } 160     }
174     assert( tmp_assign_source_1 != NULL ); 161     assert( tmp_assign_source_1 != NULL );
175     assert( var_gen == NULL ); 162     assert( var_gen == NULL );
176     var_gen = tmp_assign_source_1; 163     var_gen = tmp_assign_source_1;
177 164
n n 165     tmp_assign_source_2 = var_gen;
166  
167     assert( var_y == NULL );
168     Py_INCREF( tmp_assign_source_2 );
169     var_y = tmp_assign_source_2;
170  
178     // Tried code: 171     // Tried code:
n 179     MAKE_OR_REUSE_FRAME( cache_frame_function, codeobj_383c0af2739274bba6159a6fcb70e3f3, module___main__, sizeof(PyObject *)+sizeof(PyObject *) ); n
180     frame_function = cache_frame_function;
181  
182     // Push the new frame as the currently active one.
183     pushFrameStack( frame_function );
184  
185     // Mark the frame object as in use, ref count 1 will be up for reuse.
186     assert( Py_REFCNT( frame_function ) == 2 ); // Frame stack
187  
188     // Framed code:
189     tmp_sum_sequence_1 = var_gen;
190  
191     tmp_assign_source_2 = BUILTIN_SUM1( tmp_sum_sequence_1 );
192     if ( tmp_assign_source_2 == NULL )
193     {
194         assert( ERROR_OCCURRED() );
195  
196         FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
197  
198  
199         exception_lineno = 29;
200         type_description = "oo";
201         goto frame_exception_exit_1;
202     }
203     assert( var_y == NULL );
204     var_y = tmp_assign_source_2;
205  
206  
207 #if 0
208     RESTORE_FRAME_EXCEPTION( frame_function );
209 #endif
210  
211     // Put the previous frame back on top.
212     popFrameStack();
213  
214     goto frame_no_exception_1;
215  
216     frame_exception_exit_1:;
217  
218 #if 0
219     RESTORE_FRAME_EXCEPTION( frame_function );
220 #endif
221  
222     if ( exception_tb == NULL )
223     {
224         exception_tb = MAKE_TRACEBACK( frame_function, exception_lineno );
225     }
226     else if ( exception_tb->tb_frame != &frame_function->m_frame )
227     {
228         exception_tb = ADD_TRACEBACK( exception_tb, frame_function, exception_lineno );
229     }
230  
231     Nuitka_Frame_AttachLocals( (struct Nuitka_FrameObject *)frame_function, type_description ,var_gen, var_y );
232  
233     // Release cached frame.
234     if ( frame_function == cache_frame_function )
235     {
236         Py_DECREF( frame_function );
237     }
238     cache_frame_function = NULL;
239  
240     assertFrameObject( frame_function );
241  
242  
243     // Put the previous frame back on top.
244     popFrameStack();
245  
246     // Return the error.
247     goto try_except_handler_1;
248  
249     frame_no_exception_1:;
250  
251     tmp_return_value = PyTuple_New( 2 ); 172     tmp_return_value = PyTuple_New( 2 );
252     tmp_tuple_element_1 = var_y; 173     tmp_tuple_element_1 = var_y;
253 174
254     Py_INCREF( tmp_tuple_element_1 ); 175     Py_INCREF( tmp_tuple_element_1 );
255     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 ); 176     PyTuple_SET_ITEM( tmp_return_value, 0, tmp_tuple_element_1 );
269 190
270     Py_XDECREF( var_y ); 191     Py_XDECREF( var_y );
271     var_y = NULL; 192     var_y = NULL;
272 193
273     goto function_return_exit; 194     goto function_return_exit;
n 274     // Exception handler code: n
275     try_except_handler_1:;
276     exception_keeper_type_1 = exception_type;
277     exception_keeper_value_1 = exception_value;
278     exception_keeper_tb_1 = exception_tb;
279     exception_keeper_lineno_1 = exception_lineno;
280     exception_type = NULL;
281     exception_value = NULL;
282     exception_tb = NULL;
283     exception_lineno = -1;
284  
285     CHECK_OBJECT( (PyObject *)var_gen );
286     Py_DECREF( var_gen );
287     var_gen = NULL;
288  
289     // Re-raise.
290     exception_type = exception_keeper_type_1;
291     exception_value = exception_keeper_value_1;
292     exception_tb = exception_keeper_tb_1;
293     exception_lineno = exception_keeper_lineno_1;
294  
295     goto function_exception_exit;
296     // End of try: 195     // End of try:
297 196
298     // Return statement must have exited already. 197     // Return statement must have exited already.
299     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 198     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
300     return NULL; 199     return NULL;
301 200
t 302 function_exception_exit: t
303     assert( exception_type );
304     RESTORE_ERROR_OCCURRED( exception_type, exception_value, exception_tb );
305  
306     return NULL;
307     function_return_exit: 201     function_return_exit:
308 202
309     CHECK_OBJECT( tmp_return_value ); 203     CHECK_OBJECT( tmp_return_value );
310     assert( had_error || !ERROR_OCCURRED() ); 204     assert( had_error || !ERROR_OCCURRED() );
311     return tmp_return_value; 205     return tmp_return_value;