Construct GeneratorExpressionExit

Performance Diagrams

Construct GeneratorExpressionExit 0040000000400000008000000080000000120000000120000000160000000160000000200000000200000000240000000240000000280000000280000000320000000320000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)33522108388.11538461538461257.0CPython 2.7159652229240.03846153846155386.4243324268847Nuitka (master)159652203391.96153846153845386.4243515933403Nuitka (develop)159652329543.8846153846154386.42425870974785Nuitka (factory)Construct GeneratorExpressionExitTicks Construct GeneratorExpressionExit 0010000000100000002000000020000000300000003000000040000000400000005000000050000000600000006000000070000000700000008000000080000000CPython 3.5Nuitka (master)Nuitka (develop)Nuitka (factory)8107043388.95192307692307257.0CPython 3.566053292242.31730769230768302.77459915674143Nuitka (master)66053253395.6826923076923302.77471803485327Nuitka (develop)66053177549.0480769230769302.77494969476345Nuitka (factory)Construct GeneratorExpressionExitTicks

Source Code with Construct

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

    next(gen)

    # Take attribute lookup out of it, and built-in lookup too.
    throw = gen.throw
    exc = GeneratorExit

    try:
# construct_begin
        throw(exc)
# construct_alternative


    except exc:
        pass

    return throw, exc


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

print("OK.")

Source Code without Construct

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

    next(gen)

    # Take attribute lookup out of it, and built-in lookup too.
    throw = gen.throw
    exc = GeneratorExit

    try:
# construct_begin

# construct_alternative
        pass
# construct_end
    except exc:
        pass

    return throw, exc


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

print("OK.")

Context Diff of Source Code


Construct
Baseline
27     throw = gen.throw 27     throw = gen.throw
28     exc = GeneratorExit 28     exc = GeneratorExit
29 29
30     try: 30     try:
31 # construct_begin 31 # construct_begin
n 32         throw(exc) n 32  
33 # construct_alternative 33 # construct_alternative
t 34   t 34         pass
35   35 # construct_end
36     except exc: 36     except exc:
37         pass 37         pass
38 38
39     return throw, exc 39     return throw, exc
40 40

Context Diff of Generated Code


Construct
Baseline
56 static PyObject *const_str_digest_5ed1392909ad16e6227b8230f4582352; 56 static PyObject *const_str_digest_5ed1392909ad16e6227b8230f4582352;
57 static PyObject *const_str_plain_repeat; 57 static PyObject *const_str_plain_repeat;
58 static PyObject *const_tuple_str_digest_b9c4baf879ebd882d40843df3a4dead7_str_plain_x_tuple; 58 static PyObject *const_tuple_str_digest_b9c4baf879ebd882d40843df3a4dead7_str_plain_x_tuple;
59 static PyObject *const_tuple_none_int_pos_50000_tuple; 59 static PyObject *const_tuple_none_int_pos_50000_tuple;
60 static PyObject *const_str_digest_5971ad8ec3e05f3a87b93beaf0e9c50e; 60 static PyObject *const_str_digest_5971ad8ec3e05f3a87b93beaf0e9c50e;
n 61 static PyObject *const_tuple_type_GeneratorExit_tuple; n
62 extern PyObject *const_str_plain___doc__; 61 extern PyObject *const_str_plain___doc__;
63 extern PyObject *const_str_plain___cached__; 62 extern PyObject *const_str_plain___cached__;
64 static PyObject *const_str_plain___debug__; 63 static PyObject *const_str_plain___debug__;
65 static PyObject *module_filename_obj; 64 static PyObject *module_filename_obj;
66 65
97     PyTuple_SET_ITEM(const_tuple_str_digest_b9c4baf879ebd882d40843df3a4dead7_str_plain_x_tuple, 1, const_str_plain_x); Py_INCREF(const_str_plain_x); 96     PyTuple_SET_ITEM(const_tuple_str_digest_b9c4baf879ebd882d40843df3a4dead7_str_plain_x_tuple, 1, const_str_plain_x); Py_INCREF(const_str_plain_x);
98     const_tuple_none_int_pos_50000_tuple = PyTuple_New(2); 97     const_tuple_none_int_pos_50000_tuple = PyTuple_New(2);
99     PyTuple_SET_ITEM(const_tuple_none_int_pos_50000_tuple, 0, Py_None); Py_INCREF(Py_None); 98     PyTuple_SET_ITEM(const_tuple_none_int_pos_50000_tuple, 0, Py_None); Py_INCREF(Py_None);
100     PyTuple_SET_ITEM(const_tuple_none_int_pos_50000_tuple, 1, const_int_pos_50000); Py_INCREF(const_int_pos_50000); 99     PyTuple_SET_ITEM(const_tuple_none_int_pos_50000_tuple, 1, const_int_pos_50000); Py_INCREF(const_int_pos_50000);
101     const_str_digest_5971ad8ec3e05f3a87b93beaf0e9c50e = UNSTREAM_STRING_ASCII(&constant_bin[ 113 ], 48, 0); 100     const_str_digest_5971ad8ec3e05f3a87b93beaf0e9c50e = UNSTREAM_STRING_ASCII(&constant_bin[ 113 ], 48, 0);
n 102     const_tuple_type_GeneratorExit_tuple = PyTuple_New(1); n
103     PyTuple_SET_ITEM(const_tuple_type_GeneratorExit_tuple, 0, (PyObject *)PyExc_GeneratorExit); Py_INCREF((PyObject *)PyExc_GeneratorExit);
104     const_str_plain___debug__ = UNSTREAM_STRING_ASCII(&constant_bin[ 161 ], 9, 1); 101     const_str_plain___debug__ = UNSTREAM_STRING_ASCII(&constant_bin[ 161 ], 9, 1);
105 102
106     constants_created = true; 103     constants_created = true;
107 } 104 }
108 105
154     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL; 151     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
155     PyObject *exception_type = NULL; 152     PyObject *exception_type = NULL;
156     PyObject *exception_value = NULL; 153     PyObject *exception_value = NULL;
157     PyTracebackObject *exception_tb = NULL; 154     PyTracebackObject *exception_tb = NULL;
158     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 155     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
n n 156     static struct Nuitka_FrameObject *cache_frame_478e5c96f5f611d95e74140a5445d711 = NULL;
157     PyObject *tmp_return_value = NULL;
159     PyObject *exception_keeper_type_1; 158     PyObject *exception_keeper_type_1;
160     PyObject *exception_keeper_value_1; 159     PyObject *exception_keeper_value_1;
161     PyTracebackObject *exception_keeper_tb_1; 160     PyTracebackObject *exception_keeper_tb_1;
162     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 161     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
n 163     PyObject *exception_preserved_type_1; n
164     PyObject *exception_preserved_value_1;
165     PyTracebackObject *exception_preserved_tb_1;
166     int tmp_res;
167     bool tmp_result;
168     PyObject *exception_keeper_type_2;
169     PyObject *exception_keeper_value_2;
170     PyTracebackObject *exception_keeper_tb_2;
171     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_2;
172     static struct Nuitka_FrameObject *cache_frame_478e5c96f5f611d95e74140a5445d711 = NULL;
173     PyObject *tmp_return_value = NULL;
174     PyObject *exception_keeper_type_3;
175     PyObject *exception_keeper_value_3;
176     PyTracebackObject *exception_keeper_tb_3;
177     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
178 162
179     // Actual function body. 163     // Actual function body.
180     { 164     {
181         PyObject *tmp_assign_source_1; 165         PyObject *tmp_assign_source_1;
182         { 166         {
268             goto frame_exception_exit_1; 252             goto frame_exception_exit_1;
269         } 253         }
270         assert(var_throw == NULL); 254         assert(var_throw == NULL);
271         var_throw = tmp_assign_source_3; 255         var_throw = tmp_assign_source_3;
272     } 256     }
n 273     // Tried code: n
274     {
275         PyObject *tmp_called_name_1;
276         PyObject *tmp_call_result_1;
277         CHECK_OBJECT(var_throw);
278         tmp_called_name_1 = var_throw;
279         frame_478e5c96f5f611d95e74140a5445d711->m_frame.f_lineno = 32;
280         tmp_call_result_1 = CALL_FUNCTION_WITH_ARGS1(tmp_called_name_1, &PyTuple_GET_ITEM(const_tuple_type_GeneratorExit_tuple, 0));
281  
282         if (tmp_call_result_1 == NULL) {
283             assert(ERROR_OCCURRED());
284  
285             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
286  
287  
288             exception_lineno = 32;
289             type_description_1 = "oNo";
290             goto try_except_handler_3;
291         }
292         Py_DECREF(tmp_call_result_1);
293     }
294     goto try_end_1;
295     // Exception handler code:
296     try_except_handler_3:;
297     exception_keeper_type_1 = exception_type;
298     exception_keeper_value_1 = exception_value;
299     exception_keeper_tb_1 = exception_tb;
300     exception_keeper_lineno_1 = exception_lineno;
301     exception_type = NULL;
302     exception_value = NULL;
303     exception_tb = NULL;
304     exception_lineno = 0;
305  
306     // Preserve existing published exception.
307     exception_preserved_type_1 = EXC_TYPE(PyThreadState_GET());
308     Py_XINCREF(exception_preserved_type_1);
309     exception_preserved_value_1 = EXC_VALUE(PyThreadState_GET());
310     Py_XINCREF(exception_preserved_value_1);
311     exception_preserved_tb_1 = (PyTracebackObject *)EXC_TRACEBACK(PyThreadState_GET());
312     Py_XINCREF(exception_preserved_tb_1);
313  
314     if (exception_keeper_tb_1 == NULL) {
315         exception_keeper_tb_1 = MAKE_TRACEBACK(frame_478e5c96f5f611d95e74140a5445d711, exception_keeper_lineno_1);
316     } else if (exception_keeper_lineno_1 != 0) {
317         exception_keeper_tb_1 = ADD_TRACEBACK(exception_keeper_tb_1, frame_478e5c96f5f611d95e74140a5445d711, exception_keeper_lineno_1);
318     }
319  
320     NORMALIZE_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
321     PyException_SetTraceback(exception_keeper_value_1, (PyObject *)exception_keeper_tb_1);
322     PUBLISH_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
323     // Tried code:
324     {
325         nuitka_bool tmp_condition_result_1;
326         PyObject *tmp_operand_name_1;
327         PyObject *tmp_compexpr_left_1;
328         PyObject *tmp_compexpr_right_1;
329         tmp_compexpr_left_1 = EXC_TYPE(PyThreadState_GET());
330         tmp_compexpr_right_1 = PyExc_GeneratorExit;
331         tmp_res = EXCEPTION_MATCH_BOOL(tmp_compexpr_left_1, tmp_compexpr_right_1);
332         if (tmp_res == -1) {
333             assert(ERROR_OCCURRED());
334  
335             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
336  
337  
338             exception_lineno = 36;
339             type_description_1 = "oNo";
340             goto try_except_handler_4;
341         }
342         tmp_operand_name_1 = (tmp_res != 0) ? Py_True : Py_False;
343         tmp_res = CHECK_IF_TRUE(tmp_operand_name_1);
344         if (tmp_res == -1) {
345             assert(ERROR_OCCURRED());
346  
347             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
348  
349  
350             exception_lineno = 36;
351             type_description_1 = "oNo";
352             goto try_except_handler_4;
353         }
354         tmp_condition_result_1 = (tmp_res == 0) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
355         if (tmp_condition_result_1 == NUITKA_BOOL_TRUE) {
356             goto branch_yes_1;
357         } else {
358             goto branch_no_1;
359         }
360         branch_yes_1:;
361         tmp_result = RERAISE_EXCEPTION(&exception_type, &exception_value, &exception_tb);
362         if (unlikely(tmp_result == false)) {
363             exception_lineno = 30;
364         }
365  
366         if (exception_tb && exception_tb->tb_frame == &frame_478e5c96f5f611d95e74140a5445d711->m_frame) frame_478e5c96f5f611d95e74140a5445d711->m_frame.f_lineno = exception_tb->tb_lineno;
367         type_description_1 = "oNo";
368         goto try_except_handler_4;
369         branch_no_1:;
370     }
371     goto try_end_2;
372     // Exception handler code:
373     try_except_handler_4:;
374     exception_keeper_type_2 = exception_type;
375     exception_keeper_value_2 = exception_value;
376     exception_keeper_tb_2 = exception_tb;
377     exception_keeper_lineno_2 = exception_lineno;
378     exception_type = NULL;
379     exception_value = NULL;
380     exception_tb = NULL;
381     exception_lineno = 0;
382  
383     // Restore previous exception.
384     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
385     // Re-raise.
386     exception_type = exception_keeper_type_2;
387     exception_value = exception_keeper_value_2;
388     exception_tb = exception_keeper_tb_2;
389     exception_lineno = exception_keeper_lineno_2;
390  
391     goto frame_exception_exit_1;
392     // End of try:
393     try_end_2:;
394     // Restore previous exception.
395     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
396     goto try_end_1;
397     // exception handler codes exits in all cases
398     NUITKA_CANNOT_GET_HERE(__main__$$$function_1_calledRepeatedly);
399     return NULL;
400     // End of try:
401     try_end_1:;
402 257
403 #if 0 258 #if 0
404     RESTORE_FRAME_EXCEPTION(frame_478e5c96f5f611d95e74140a5445d711); 259     RESTORE_FRAME_EXCEPTION(frame_478e5c96f5f611d95e74140a5445d711);
405 #endif 260 #endif
406 261
473     var_throw = NULL; 328     var_throw = NULL;
474 329
475     goto function_return_exit; 330     goto function_return_exit;
476     // Exception handler code: 331     // Exception handler code:
477     try_except_handler_2:; 332     try_except_handler_2:;
n 478     exception_keeper_type_3 = exception_type; n 333     exception_keeper_type_1 = exception_type;
479     exception_keeper_value_3 = exception_value; 334     exception_keeper_value_1 = exception_value;
480     exception_keeper_tb_3 = exception_tb; 335     exception_keeper_tb_1 = exception_tb;
481     exception_keeper_lineno_3 = exception_lineno; 336     exception_keeper_lineno_1 = exception_lineno;
482     exception_type = NULL; 337     exception_type = NULL;
483     exception_value = NULL; 338     exception_value = NULL;
484     exception_tb = NULL; 339     exception_tb = NULL;
485     exception_lineno = 0; 340     exception_lineno = 0;
486 341
487     CHECK_OBJECT((PyObject *)var_gen); 342     CHECK_OBJECT((PyObject *)var_gen);
488     Py_DECREF(var_gen); 343     Py_DECREF(var_gen);
489     var_gen = NULL; 344     var_gen = NULL;
490 345
n 491     Py_XDECREF(var_throw); n
492     var_throw = NULL;
493  
494     // Re-raise. 346     // Re-raise.
t 495     exception_type = exception_keeper_type_3; t 347     exception_type = exception_keeper_type_1;
496     exception_value = exception_keeper_value_3; 348     exception_value = exception_keeper_value_1;
497     exception_tb = exception_keeper_tb_3; 349     exception_tb = exception_keeper_tb_1;
498     exception_lineno = exception_keeper_lineno_3; 350     exception_lineno = exception_keeper_lineno_1;
499 351
500     goto function_exception_exit; 352     goto function_exception_exit;
501     // End of try: 353     // End of try:
502 354
503     // Return statement must have exited already. 355     // Return statement must have exited already.