Construct GeneratorUsage

Performance Diagrams

Construct GeneratorUsage 001000000010000000200000002000000030000000300000004000000040000000CPython 2.7Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)4324355173.61538461538461257.0CPython 2.70196.30769230769232504.11538461538464Nuitka (historic)17700158319.0000000000001402.96778570698143Nuitka (master)17699260441.69230769230774402.97291733031614Nuitka (develop)17700584564.3846153846155402.9653513288739Nuitka (factory)Construct GeneratorUsageTicks Construct GeneratorUsage 0010000000100000002000000020000000300000003000000040000000400000005000000050000000CPython 3.5Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)5037516173.61538461538461257.0CPython 3.50196.30769230769232504.11538461538464Nuitka (historic)16700143319.0000000000001422.1928224110291Nuitka (master)16700215441.69230769230774422.1924692149829Nuitka (develop)16701118564.3846153846155422.1880395479034Nuitka (factory)Construct GeneratorUsageTicks

Source Code with Construct

def calledRepeatedly():
    # We measure making a generator iterator step or not.
    def generator():
        yield 1
        yield 2
        yield 3

    gen = generator()

    x = next(gen)
# construct_begin
    next(gen)
# construct_end

    return x

for x in xrange(50000):
    calledRepeatedly()

print("OK.")

Source Code without Construct

def calledRepeatedly():
    # We measure making a generator iterator step or not.
    def generator():
        yield 1
        yield 2
        yield 3

    gen = generator()

    x = next(gen)
# construct_begin



    return x

for x in xrange(50000):
    calledRepeatedly()

print("OK.")

Context Diff of Source Code


Construct
Baseline
29 29
30     gen = generator() 30     gen = generator()
31 31
32     x = next(gen) 32     x = next(gen)
33 # construct_begin 33 # construct_begin
t 34     next(gen) t 34  
35 # construct_end 35  
36 36
37     return x 37     return x
38 38
39 for x in xrange(50000): 39 for x in xrange(50000):
40     calledRepeatedly() 40     calledRepeatedly()

Context Diff of Generated Code


Construct
Baseline
144     PyObject *tmp_assign_source_2; 144     PyObject *tmp_assign_source_2;
145     PyObject *tmp_assign_source_3; 145     PyObject *tmp_assign_source_3;
146     PyObject *tmp_called_name_1; 146     PyObject *tmp_called_name_1;
147     PyObject *tmp_frame_locals; 147     PyObject *tmp_frame_locals;
148     PyObject *tmp_return_value; 148     PyObject *tmp_return_value;
n 149     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused; n
150     PyObject *tmp_value_name_1; 149     PyObject *tmp_value_name_1;
n 151     PyObject *tmp_value_name_2; n
152     static PyFrameObject *cache_frame_function = NULL; 150     static PyFrameObject *cache_frame_function = NULL;
153 151
154     PyFrameObject *frame_function; 152     PyFrameObject *frame_function;
155 153
156     tmp_return_value = NULL; 154     tmp_return_value = NULL;
215         goto frame_exception_exit_1; 213         goto frame_exception_exit_1;
216     } 214     }
217     assert( var_x == NULL ); 215     assert( var_x == NULL );
218     var_x = tmp_assign_source_3; 216     var_x = tmp_assign_source_3;
219 217
n 220     tmp_value_name_2 = var_gen; n
221  
222     if ( tmp_value_name_2 == NULL )
223     {
224  
225         exception_type = PyExc_UnboundLocalError;
226         Py_INCREF( exception_type );
227         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "gen" );
228         exception_tb = NULL;
229         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
230         CHAIN_EXCEPTION( exception_value );
231  
232         exception_lineno = 34;
233         goto frame_exception_exit_1;
234     }
235  
236     tmp_unused = ITERATOR_NEXT( tmp_value_name_2 );
237     if ( tmp_unused == NULL )
238     {
239         if ( !ERROR_OCCURRED() )
240         {
241             exception_type = PyExc_StopIteration;
242             Py_INCREF( exception_type );
243             exception_value = NULL;
244             exception_tb = NULL;
245         }
246         else
247         {
248             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
249         }
250  
251  
252         exception_lineno = 34;
253         goto frame_exception_exit_1;
254     }
255     Py_DECREF( tmp_unused );
256 218
257 #if 0 219 #if 0
258     RESTORE_FRAME_EXCEPTION( frame_function ); 220     RESTORE_FRAME_EXCEPTION( frame_function );
259 #endif 221 #endif
260     // Put the previous frame back on top. 222     // Put the previous frame back on top.
341     goto try_except_handler_1; 303     goto try_except_handler_1;
342 304
343     frame_no_exception_1:; 305     frame_no_exception_1:;
344 306
345     tmp_return_value = var_x; 307     tmp_return_value = var_x;
n 346   n
347     if ( tmp_return_value == NULL )
348     {
349  
350         exception_type = PyExc_UnboundLocalError;
351         Py_INCREF( exception_type );
352         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "x" );
353         exception_tb = NULL;
354         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
355         CHAIN_EXCEPTION( exception_value );
356  
357  
358         goto try_except_handler_1;
359     }
360 308
361     Py_INCREF( tmp_return_value ); 309     Py_INCREF( tmp_return_value );
362     goto try_return_handler_1; 310     goto try_return_handler_1;
363     // tried codes exits in all cases 311     // tried codes exits in all cases
364     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 312     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
389     Py_XDECREF( var_generator ); 337     Py_XDECREF( var_generator );
390     var_generator = NULL; 338     var_generator = NULL;
391 339
392     Py_XDECREF( var_gen ); 340     Py_XDECREF( var_gen );
393     var_gen = NULL; 341     var_gen = NULL;
t 394   t
395     Py_XDECREF( var_x );
396     var_x = NULL;
397 342
398     // Re-raise. 343     // Re-raise.
399     exception_type = exception_keeper_type_1; 344     exception_type = exception_keeper_type_1;
400     exception_value = exception_keeper_value_1; 345     exception_value = exception_keeper_value_1;
401     exception_tb = exception_keeper_tb_1; 346     exception_tb = exception_keeper_tb_1;