Construct GeneratorUsage

Performance Diagrams

Construct GeneratorUsage 001000000010000000200000002000000030000000300000004000000040000000CPython 2.7Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)4324355173.61538461538461257.0CPython 2.70196.30769230769232504.11538461538464Nuitka (historic)17749854319.0000000000001402.6837977857803Nuitka (master)17749520441.69230769230774402.68570642964863Nuitka (develop)17749520564.3846153846155402.68570642964863Nuitka (factory)Construct GeneratorUsageTicks Construct GeneratorUsage 0010000000100000002000000020000000300000003000000040000000400000005000000050000000CPython 3.5Nuitka (historic)Nuitka (master)Nuitka (develop)Nuitka (factory)5037516173.61538461538461257.0CPython 3.50196.30769230769232504.11538461538464Nuitka (historic)16550311319.0000000000001422.92782338318864Nuitka (master)16550025441.69230769230774422.92922635637217Nuitka (develop)16549483564.3846153846155422.93188513772003Nuitka (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
142     PyObject *tmp_assign_source_1; 142     PyObject *tmp_assign_source_1;
143     PyObject *tmp_assign_source_2; 143     PyObject *tmp_assign_source_2;
144     PyObject *tmp_assign_source_3; 144     PyObject *tmp_assign_source_3;
145     PyObject *tmp_called_name_1; 145     PyObject *tmp_called_name_1;
146     PyObject *tmp_return_value; 146     PyObject *tmp_return_value;
n 147     NUITKA_MAY_BE_UNUSED PyObject *tmp_unused; n
148     PyObject *tmp_value_name_1; 147     PyObject *tmp_value_name_1;
n 149     PyObject *tmp_value_name_2; n
150     static struct Nuitka_FrameObject *cache_frame_f612342abc679987e34962a48d5d8ef9 = NULL; 148     static struct Nuitka_FrameObject *cache_frame_f612342abc679987e34962a48d5d8ef9 = NULL;
151 149
152     struct Nuitka_FrameObject *frame_f612342abc679987e34962a48d5d8ef9; 150     struct Nuitka_FrameObject *frame_f612342abc679987e34962a48d5d8ef9;
153 151
154     char const *type_description; 152     char const *type_description;
213         goto frame_exception_exit_1; 211         goto frame_exception_exit_1;
214     } 212     }
215     assert( var_x == NULL ); 213     assert( var_x == NULL );
216     var_x = tmp_assign_source_3; 214     var_x = tmp_assign_source_3;
217 215
n 218     tmp_value_name_2 = var_gen; n
219  
220     if ( tmp_value_name_2 == NULL )
221     {
222  
223         exception_type = PyExc_UnboundLocalError;
224         Py_INCREF( exception_type );
225         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "gen" );
226         exception_tb = NULL;
227         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
228         CHAIN_EXCEPTION( exception_value );
229  
230         exception_lineno = 34;
231         type_description = "ooo";
232         goto frame_exception_exit_1;
233     }
234  
235     tmp_unused = ITERATOR_NEXT( tmp_value_name_2 );
236     if ( tmp_unused == NULL )
237     {
238         if ( !ERROR_OCCURRED() )
239         {
240             exception_type = PyExc_StopIteration;
241             Py_INCREF( exception_type );
242             exception_value = NULL;
243             exception_tb = NULL;
244         }
245         else
246         {
247             FETCH_ERROR_OCCURRED( &exception_type, &exception_value, &exception_tb );
248         }
249  
250  
251         type_description = "ooo";
252         exception_lineno = 34;
253         goto frame_exception_exit_1;
254     }
255     Py_DECREF( tmp_unused );
256 216
257 #if 0 217 #if 0
258     RESTORE_FRAME_EXCEPTION( frame_f612342abc679987e34962a48d5d8ef9 ); 218     RESTORE_FRAME_EXCEPTION( frame_f612342abc679987e34962a48d5d8ef9 );
259 #endif 219 #endif
260 220
298 258
299     frame_no_exception_1:; 259     frame_no_exception_1:;
300 260
301     tmp_return_value = var_x; 261     tmp_return_value = var_x;
302 262
n 303     if ( tmp_return_value == NULL ) n 263     CHECK_OBJECT( tmp_return_value );
304     {
305  
306         exception_type = PyExc_UnboundLocalError;
307         Py_INCREF( exception_type );
308         exception_value = PyUnicode_FromFormat( "local variable '%s' referenced before assignment", "x" );
309         exception_tb = NULL;
310         NORMALIZE_EXCEPTION( &exception_type, &exception_value, &exception_tb );
311         CHAIN_EXCEPTION( exception_value );
312  
313  
314  
315         goto try_except_handler_1;
316     }
317  
318     Py_INCREF( tmp_return_value ); 264     Py_INCREF( tmp_return_value );
319     goto try_return_handler_1; 265     goto try_return_handler_1;
320     // tried codes exits in all cases 266     // tried codes exits in all cases
321     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly ); 267     NUITKA_CANNOT_GET_HERE( __main__$$$function_1_calledRepeatedly );
322     return NULL; 268     return NULL;
346     Py_XDECREF( var_generator ); 292     Py_XDECREF( var_generator );
347     var_generator = NULL; 293     var_generator = NULL;
348 294
349     Py_XDECREF( var_gen ); 295     Py_XDECREF( var_gen );
350     var_gen = NULL; 296     var_gen = NULL;
t 351   t
352     Py_XDECREF( var_x );
353     var_x = NULL;
354 297
355     // Re-raise. 298     // Re-raise.
356     exception_type = exception_keeper_type_1; 299     exception_type = exception_keeper_type_1;
357     exception_value = exception_keeper_value_1; 300     exception_value = exception_keeper_value_1;
358     exception_tb = exception_keeper_tb_1; 301     exception_tb = exception_keeper_tb_1;