Construct GeneratorExpressionExit

Performance Diagrams

Construct GeneratorExpressionExit 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000CPython 2.7Nuitka (main)Nuitka (develop)Nuitka (factory)27526616088.11538461538461257.0CPython 2.7127750107240.03846153846155389.42995860456824Nuitka (main)127750096391.96153846153845389.42996847962604Nuitka (develop)127750096543.8846153846154389.42996847962604Nuitka (factory)Construct GeneratorExpressionExitTicks Construct GeneratorExpressionExit 0010000000100000002000000020000000300000003000000040000000400000005000000050000000600000006000000070000000700000008000000080000000CPython 3.8Nuitka (main)Nuitka (develop)Nuitka (factory)8222017288.95192307692307257.0CPython 3.860351119242.31730769230768322.7281456826584Nuitka (main)60351467395.6826923076923322.72709975740975Nuitka (develop)60351467549.0480769230769322.72709975740975Nuitka (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
106 #endif 106 #endif
107 107
108     // Local variable declarations. 108     // Local variable declarations.
109     PyObject *var_gen = NULL; 109     PyObject *var_gen = NULL;
110     PyObject *var_throw = NULL; 110     PyObject *var_throw = NULL;
n 111     PyObject *var_exc = NULL; n
112     PyObject *tmp_genexpr_1__$0 = NULL; 111     PyObject *tmp_genexpr_1__$0 = NULL;
113     struct Nuitka_FrameObject *frame_d75634ff2f0de39fb9c3db074cf8d79a; 112     struct Nuitka_FrameObject *frame_d75634ff2f0de39fb9c3db074cf8d79a;
114     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL; 113     NUITKA_MAY_BE_UNUSED char const *type_description_1 = NULL;
115     NUITKA_MAY_BE_UNUSED nuitka_void tmp_unused; 114     NUITKA_MAY_BE_UNUSED nuitka_void tmp_unused;
116     PyObject *exception_type = NULL; 115     PyObject *exception_type = NULL;
117     PyObject *exception_value = NULL; 116     PyObject *exception_value = NULL;
118     PyTracebackObject *exception_tb = NULL; 117     PyTracebackObject *exception_tb = NULL;
119     NUITKA_MAY_BE_UNUSED int exception_lineno = 0; 118     NUITKA_MAY_BE_UNUSED int exception_lineno = 0;
n n 119     static struct Nuitka_FrameObject *cache_frame_d75634ff2f0de39fb9c3db074cf8d79a = NULL;
120     PyObject *tmp_return_value = NULL;
120     PyObject *exception_keeper_type_1; 121     PyObject *exception_keeper_type_1;
121     PyObject *exception_keeper_value_1; 122     PyObject *exception_keeper_value_1;
122     PyTracebackObject *exception_keeper_tb_1; 123     PyTracebackObject *exception_keeper_tb_1;
123     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1; 124     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_1;
n 124     PyObject *exception_preserved_type_1; n
125     PyObject *exception_preserved_value_1;
126     PyTracebackObject *exception_preserved_tb_1;
127     int tmp_res;
128     bool tmp_result;
129     PyObject *exception_keeper_type_2;
130     PyObject *exception_keeper_value_2;
131     PyTracebackObject *exception_keeper_tb_2;
132     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_2;
133     static struct Nuitka_FrameObject *cache_frame_d75634ff2f0de39fb9c3db074cf8d79a = NULL;
134     PyObject *tmp_return_value = NULL;
135     PyObject *exception_keeper_type_3;
136     PyObject *exception_keeper_value_3;
137     PyTracebackObject *exception_keeper_tb_3;
138     NUITKA_MAY_BE_UNUSED int exception_keeper_lineno_3;
139 125
140     // Actual function body. 126     // Actual function body.
141     { 127     {
142         PyObject *tmp_assign_source_1; 128         PyObject *tmp_assign_source_1;
143         { 129         {
217             } else { 203             } else {
218                 FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb); 204                 FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
219             } 205             }
220 206
221 207
n 222             type_description_1 = "ooo"; n 208             type_description_1 = "ooN";
223             exception_lineno = 24; 209             exception_lineno = 24;
224             goto frame_exception_exit_1; 210             goto frame_exception_exit_1;
225         } 211         }
226         Py_DECREF(tmp_next_value_1); 212         Py_DECREF(tmp_next_value_1);
227     } 213     }
236 222
237             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb); 223             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
238 224
239 225
240             exception_lineno = 27; 226             exception_lineno = 27;
n 241             type_description_1 = "ooo"; n 227             type_description_1 = "ooN";
242             goto frame_exception_exit_1; 228             goto frame_exception_exit_1;
243         } 229         }
244         assert(var_throw == NULL); 230         assert(var_throw == NULL);
245         var_throw = tmp_assign_source_3; 231         var_throw = tmp_assign_source_3;
246     } 232     }
n 247     { n
248         PyObject *tmp_assign_source_4;
249         tmp_assign_source_4 = PyExc_GeneratorExit;
250         assert(var_exc == NULL);
251         Py_INCREF(tmp_assign_source_4);
252         var_exc = tmp_assign_source_4;
253     }
254     // Tried code:
255     {
256         PyObject *tmp_called_value_1;
257         PyObject *tmp_call_result_1;
258         PyObject *tmp_args_element_value_1;
259         CHECK_OBJECT(var_throw);
260         tmp_called_value_1 = var_throw;
261         CHECK_OBJECT(var_exc);
262         tmp_args_element_value_1 = var_exc;
263         frame_d75634ff2f0de39fb9c3db074cf8d79a->m_frame.f_lineno = 32;
264         tmp_call_result_1 = CALL_FUNCTION_WITH_SINGLE_ARG(tmp_called_value_1, tmp_args_element_value_1);
265         if (tmp_call_result_1 == NULL) {
266             assert(ERROR_OCCURRED());
267  
268             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
269  
270  
271             exception_lineno = 32;
272             type_description_1 = "ooo";
273             goto try_except_handler_3;
274         }
275         Py_DECREF(tmp_call_result_1);
276     }
277     goto try_end_1;
278     // Exception handler code:
279     try_except_handler_3:;
280     exception_keeper_type_1 = exception_type;
281     exception_keeper_value_1 = exception_value;
282     exception_keeper_tb_1 = exception_tb;
283     exception_keeper_lineno_1 = exception_lineno;
284     exception_type = NULL;
285     exception_value = NULL;
286     exception_tb = NULL;
287     exception_lineno = 0;
288  
289     // Preserve existing published exception id 1.
290     GET_CURRENT_EXCEPTION(&exception_preserved_type_1, &exception_preserved_value_1, &exception_preserved_tb_1);
291  
292     if (exception_keeper_tb_1 == NULL) {
293         exception_keeper_tb_1 = MAKE_TRACEBACK(frame_d75634ff2f0de39fb9c3db074cf8d79a, exception_keeper_lineno_1);
294     } else if (exception_keeper_lineno_1 != 0) {
295         exception_keeper_tb_1 = ADD_TRACEBACK(exception_keeper_tb_1, frame_d75634ff2f0de39fb9c3db074cf8d79a, exception_keeper_lineno_1);
296     }
297  
298     NORMALIZE_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
299     ATTACH_TRACEBACK_TO_EXCEPTION_VALUE(exception_keeper_value_1, exception_keeper_tb_1);
300     PUBLISH_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
301     // Tried code:
302     {
303         bool tmp_condition_result_1;
304         PyObject *tmp_compexpr_left_1;
305         PyObject *tmp_compexpr_right_1;
306         tmp_compexpr_left_1 = EXC_TYPE(PyThreadState_GET());
307         CHECK_OBJECT(var_exc);
308         tmp_compexpr_right_1 = var_exc;
309         tmp_res = EXCEPTION_MATCH_BOOL(tmp_compexpr_left_1, tmp_compexpr_right_1);
310         if (tmp_res == -1) {
311             assert(ERROR_OCCURRED());
312  
313             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
314  
315  
316             exception_lineno = 36;
317             type_description_1 = "ooo";
318             goto try_except_handler_4;
319         }
320         tmp_condition_result_1 = (tmp_res == 0) ? true : false;
321         if (tmp_condition_result_1 != false) {
322             goto branch_yes_1;
323         } else {
324             goto branch_no_1;
325         }
326     }
327     branch_yes_1:;
328     tmp_result = RERAISE_EXCEPTION(&exception_type, &exception_value, &exception_tb);
329     if (unlikely(tmp_result == false)) {
330         exception_lineno = 30;
331     }
332  
333     if (exception_tb && exception_tb->tb_frame == &frame_d75634ff2f0de39fb9c3db074cf8d79a->m_frame) frame_d75634ff2f0de39fb9c3db074cf8d79a->m_frame.f_lineno = exception_tb->tb_lineno;
334     type_description_1 = "ooo";
335     goto try_except_handler_4;
336     branch_no_1:;
337     goto try_end_2;
338     // Exception handler code:
339     try_except_handler_4:;
340     exception_keeper_type_2 = exception_type;
341     exception_keeper_value_2 = exception_value;
342     exception_keeper_tb_2 = exception_tb;
343     exception_keeper_lineno_2 = exception_lineno;
344     exception_type = NULL;
345     exception_value = NULL;
346     exception_tb = NULL;
347     exception_lineno = 0;
348  
349     // Restore previous exception id 1.
350     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
351  
352     // Re-raise.
353     exception_type = exception_keeper_type_2;
354     exception_value = exception_keeper_value_2;
355     exception_tb = exception_keeper_tb_2;
356     exception_lineno = exception_keeper_lineno_2;
357  
358     goto frame_exception_exit_1;
359     // End of try:
360     try_end_2:;
361     // Restore previous exception id 1.
362     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
363  
364     goto try_end_1;
365     NUITKA_CANNOT_GET_HERE("exception handler codes exits in all cases");
366     return NULL;
367     // End of try:
368     try_end_1:;
369 233
370 #if 0 234 #if 0
371     RESTORE_FRAME_EXCEPTION(frame_d75634ff2f0de39fb9c3db074cf8d79a); 235     RESTORE_FRAME_EXCEPTION(frame_d75634ff2f0de39fb9c3db074cf8d79a);
372 #endif 236 #endif
373 237
392     Nuitka_Frame_AttachLocals( 256     Nuitka_Frame_AttachLocals(
393         frame_d75634ff2f0de39fb9c3db074cf8d79a, 257         frame_d75634ff2f0de39fb9c3db074cf8d79a,
394         type_description_1, 258         type_description_1,
395         var_gen, 259         var_gen,
396         var_throw, 260         var_throw,
n 397         var_exc n 261         NULL
398     ); 262     );
399 263
400 264
401     // Release cached frame if used for exception. 265     // Release cached frame if used for exception.
402     if (frame_d75634ff2f0de39fb9c3db074cf8d79a == cache_frame_d75634ff2f0de39fb9c3db074cf8d79a) { 266     if (frame_d75634ff2f0de39fb9c3db074cf8d79a == cache_frame_d75634ff2f0de39fb9c3db074cf8d79a) {
422         PyObject *tmp_tuple_element_1; 286         PyObject *tmp_tuple_element_1;
423         CHECK_OBJECT(var_throw); 287         CHECK_OBJECT(var_throw);
424         tmp_tuple_element_1 = var_throw; 288         tmp_tuple_element_1 = var_throw;
425         tmp_return_value = PyTuple_New(2); 289         tmp_return_value = PyTuple_New(2);
426         PyTuple_SET_ITEM0(tmp_return_value, 0, tmp_tuple_element_1); 290         PyTuple_SET_ITEM0(tmp_return_value, 0, tmp_tuple_element_1);
n 427         CHECK_OBJECT(var_exc); n
428         tmp_tuple_element_1 = var_exc; 291         tmp_tuple_element_1 = PyExc_GeneratorExit;
429         PyTuple_SET_ITEM0(tmp_return_value, 1, tmp_tuple_element_1); 292         PyTuple_SET_ITEM0(tmp_return_value, 1, tmp_tuple_element_1);
430         goto try_return_handler_2; 293         goto try_return_handler_2;
431     } 294     }
432     NUITKA_CANNOT_GET_HERE("tried codes exits in all cases"); 295     NUITKA_CANNOT_GET_HERE("tried codes exits in all cases");
433     return NULL; 296     return NULL;
437     Py_DECREF(var_gen); 300     Py_DECREF(var_gen);
438     var_gen = NULL; 301     var_gen = NULL;
439     CHECK_OBJECT(var_throw); 302     CHECK_OBJECT(var_throw);
440     Py_DECREF(var_throw); 303     Py_DECREF(var_throw);
441     var_throw = NULL; 304     var_throw = NULL;
n 442     CHECK_OBJECT(var_exc); n
443     Py_DECREF(var_exc);
444     var_exc = NULL;
445     goto function_return_exit; 305     goto function_return_exit;
446     // Exception handler code: 306     // Exception handler code:
447     try_except_handler_2:; 307     try_except_handler_2:;
n 448     exception_keeper_type_3 = exception_type; n 308     exception_keeper_type_1 = exception_type;
449     exception_keeper_value_3 = exception_value; 309     exception_keeper_value_1 = exception_value;
450     exception_keeper_tb_3 = exception_tb; 310     exception_keeper_tb_1 = exception_tb;
451     exception_keeper_lineno_3 = exception_lineno; 311     exception_keeper_lineno_1 = exception_lineno;
452     exception_type = NULL; 312     exception_type = NULL;
453     exception_value = NULL; 313     exception_value = NULL;
454     exception_tb = NULL; 314     exception_tb = NULL;
455     exception_lineno = 0; 315     exception_lineno = 0;
456 316
457     CHECK_OBJECT(var_gen); 317     CHECK_OBJECT(var_gen);
458     Py_DECREF(var_gen); 318     Py_DECREF(var_gen);
459     var_gen = NULL; 319     var_gen = NULL;
n 460     Py_XDECREF(var_throw); n
461     var_throw = NULL;
462     Py_XDECREF(var_exc);
463     var_exc = NULL;
464     // Re-raise. 320     // Re-raise.
t 465     exception_type = exception_keeper_type_3; t 321     exception_type = exception_keeper_type_1;
466     exception_value = exception_keeper_value_3; 322     exception_value = exception_keeper_value_1;
467     exception_tb = exception_keeper_tb_3; 323     exception_tb = exception_keeper_tb_1;
468     exception_lineno = exception_keeper_lineno_3; 324     exception_lineno = exception_keeper_lineno_1;
469 325
470     goto function_exception_exit; 326     goto function_exception_exit;
471     // End of try: 327     // End of try:
472 328
473     NUITKA_CANNOT_GET_HERE("Return statement must have exited already."); 329     NUITKA_CANNOT_GET_HERE("Return statement must have exited already.");