Construct GeneratorExpressionExit

Performance Diagrams

Construct GeneratorExpressionExit 002000000020000000400000004000000060000000600000008000000080000000100000000100000000120000000120000000140000000140000000160000000160000000180000000180000000200000000200000000220000000220000000240000000240000000260000000260000000CPython 2.7Nuitka (master)Nuitka (develop)Nuitka (factory)27526616088.11538461538461257.0CPython 2.7127750064240.03846153846155389.4299972070668Nuitka (master)127750064391.96153846153845389.4299972070668Nuitka (develop)127750064543.8846153846154389.4299972070668Nuitka (factory)Construct GeneratorExpressionExitTicks Construct GeneratorExpressionExit 0010000000100000002000000020000000300000003000000040000000400000005000000050000000600000006000000070000000700000008000000080000000CPython 3.8Nuitka (master)Nuitka (develop)Nuitka (factory)8222017288.95192307692307257.0CPython 3.858952050242.31730769230768326.93309278540175Nuitka (master)58952025395.6826923076923326.9331679237099Nuitka (develop)58951676549.0480769230769326.93421685449084Nuitka (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_f69dca291b4bd8303b845c5fa6e6bf12; 112     struct Nuitka_FrameObject *frame_f69dca291b4bd8303b845c5fa6e6bf12;
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_f69dca291b4bd8303b845c5fa6e6bf12 = 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_f69dca291b4bd8303b845c5fa6e6bf12 = 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         {
220             } else { 206             } else {
221                 FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb); 207                 FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
222             } 208             }
223 209
224 210
n 225             type_description_1 = "ooo"; n 211             type_description_1 = "ooN";
226             exception_lineno = 24; 212             exception_lineno = 24;
227             goto frame_exception_exit_1; 213             goto frame_exception_exit_1;
228         } 214         }
229         Py_DECREF(tmp_next_value_1); 215         Py_DECREF(tmp_next_value_1);
230     } 216     }
239 225
240             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb); 226             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
241 227
242 228
243             exception_lineno = 27; 229             exception_lineno = 27;
n 244             type_description_1 = "ooo"; n 230             type_description_1 = "ooN";
245             goto frame_exception_exit_1; 231             goto frame_exception_exit_1;
246         } 232         }
247         assert(var_throw == NULL); 233         assert(var_throw == NULL);
248         var_throw = tmp_assign_source_3; 234         var_throw = tmp_assign_source_3;
249     } 235     }
n 250     { n
251         PyObject *tmp_assign_source_4;
252         tmp_assign_source_4 = PyExc_GeneratorExit;
253         assert(var_exc == NULL);
254         Py_INCREF(tmp_assign_source_4);
255         var_exc = tmp_assign_source_4;
256     }
257     // Tried code:
258     {
259         PyObject *tmp_called_name_1;
260         PyObject *tmp_call_result_1;
261         PyObject *tmp_args_element_name_1;
262         CHECK_OBJECT(var_throw);
263         tmp_called_name_1 = var_throw;
264         CHECK_OBJECT(var_exc);
265         tmp_args_element_name_1 = var_exc;
266         frame_f69dca291b4bd8303b845c5fa6e6bf12->m_frame.f_lineno = 32;
267         tmp_call_result_1 = CALL_FUNCTION_WITH_SINGLE_ARG(tmp_called_name_1, tmp_args_element_name_1);
268         if (tmp_call_result_1 == NULL) {
269             assert(ERROR_OCCURRED());
270  
271             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
272  
273  
274             exception_lineno = 32;
275             type_description_1 = "ooo";
276             goto try_except_handler_3;
277         }
278         Py_DECREF(tmp_call_result_1);
279     }
280     goto try_end_1;
281     // Exception handler code:
282     try_except_handler_3:;
283     exception_keeper_type_1 = exception_type;
284     exception_keeper_value_1 = exception_value;
285     exception_keeper_tb_1 = exception_tb;
286     exception_keeper_lineno_1 = exception_lineno;
287     exception_type = NULL;
288     exception_value = NULL;
289     exception_tb = NULL;
290     exception_lineno = 0;
291  
292     // Preserve existing published exception id 1.
293     GET_CURRENT_EXCEPTION(&exception_preserved_type_1, &exception_preserved_value_1, &exception_preserved_tb_1);
294  
295     if (exception_keeper_tb_1 == NULL) {
296         exception_keeper_tb_1 = MAKE_TRACEBACK(frame_f69dca291b4bd8303b845c5fa6e6bf12, exception_keeper_lineno_1);
297     } else if (exception_keeper_lineno_1 != 0) {
298         exception_keeper_tb_1 = ADD_TRACEBACK(exception_keeper_tb_1, frame_f69dca291b4bd8303b845c5fa6e6bf12, exception_keeper_lineno_1);
299     }
300  
301     NORMALIZE_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
302     ATTACH_TRACEBACK_TO_EXCEPTION_VALUE(exception_keeper_value_1, exception_keeper_tb_1);
303     PUBLISH_EXCEPTION(&exception_keeper_type_1, &exception_keeper_value_1, &exception_keeper_tb_1);
304     // Tried code:
305     {
306         bool tmp_condition_result_1;
307         PyObject *tmp_compexpr_left_1;
308         PyObject *tmp_compexpr_right_1;
309         tmp_compexpr_left_1 = EXC_TYPE(PyThreadState_GET());
310         CHECK_OBJECT(var_exc);
311         tmp_compexpr_right_1 = var_exc;
312         tmp_res = EXCEPTION_MATCH_BOOL(tmp_compexpr_left_1, tmp_compexpr_right_1);
313         if (tmp_res == -1) {
314             assert(ERROR_OCCURRED());
315  
316             FETCH_ERROR_OCCURRED(&exception_type, &exception_value, &exception_tb);
317  
318  
319             exception_lineno = 36;
320             type_description_1 = "ooo";
321             goto try_except_handler_4;
322         }
323         tmp_condition_result_1 = (tmp_res == 0) ? true : false;
324         if (tmp_condition_result_1 != false) {
325             goto branch_yes_1;
326         } else {
327             goto branch_no_1;
328         }
329     }
330     branch_yes_1:;
331     tmp_result = RERAISE_EXCEPTION(&exception_type, &exception_value, &exception_tb);
332     if (unlikely(tmp_result == false)) {
333         exception_lineno = 30;
334     }
335  
336     if (exception_tb && exception_tb->tb_frame == &frame_f69dca291b4bd8303b845c5fa6e6bf12->m_frame) frame_f69dca291b4bd8303b845c5fa6e6bf12->m_frame.f_lineno = exception_tb->tb_lineno;
337     type_description_1 = "ooo";
338     goto try_except_handler_4;
339     branch_no_1:;
340     goto try_end_2;
341     // Exception handler code:
342     try_except_handler_4:;
343     exception_keeper_type_2 = exception_type;
344     exception_keeper_value_2 = exception_value;
345     exception_keeper_tb_2 = exception_tb;
346     exception_keeper_lineno_2 = exception_lineno;
347     exception_type = NULL;
348     exception_value = NULL;
349     exception_tb = NULL;
350     exception_lineno = 0;
351  
352     // Restore previous exception id 1.
353     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
354  
355     // Re-raise.
356     exception_type = exception_keeper_type_2;
357     exception_value = exception_keeper_value_2;
358     exception_tb = exception_keeper_tb_2;
359     exception_lineno = exception_keeper_lineno_2;
360  
361     goto frame_exception_exit_1;
362     // End of try:
363     try_end_2:;
364     // Restore previous exception id 1.
365     SET_CURRENT_EXCEPTION(exception_preserved_type_1, exception_preserved_value_1, exception_preserved_tb_1);
366  
367     goto try_end_1;
368     NUITKA_CANNOT_GET_HERE("exception handler codes exits in all cases");
369     return NULL;
370     // End of try:
371     try_end_1:;
372 236
373 #if 0 237 #if 0
374     RESTORE_FRAME_EXCEPTION(frame_f69dca291b4bd8303b845c5fa6e6bf12); 238     RESTORE_FRAME_EXCEPTION(frame_f69dca291b4bd8303b845c5fa6e6bf12);
375 #endif 239 #endif
376 240
395     Nuitka_Frame_AttachLocals( 259     Nuitka_Frame_AttachLocals(
396         frame_f69dca291b4bd8303b845c5fa6e6bf12, 260         frame_f69dca291b4bd8303b845c5fa6e6bf12,
397         type_description_1, 261         type_description_1,
398         var_gen, 262         var_gen,
399         var_throw, 263         var_throw,
n 400         var_exc n 264         NULL
401     ); 265     );
402 266
403 267
404     // Release cached frame if used for exception. 268     // Release cached frame if used for exception.
405     if (frame_f69dca291b4bd8303b845c5fa6e6bf12 == cache_frame_f69dca291b4bd8303b845c5fa6e6bf12) { 269     if (frame_f69dca291b4bd8303b845c5fa6e6bf12 == cache_frame_f69dca291b4bd8303b845c5fa6e6bf12) {
425         PyObject *tmp_tuple_element_1; 289         PyObject *tmp_tuple_element_1;
426         CHECK_OBJECT(var_throw); 290         CHECK_OBJECT(var_throw);
427         tmp_tuple_element_1 = var_throw; 291         tmp_tuple_element_1 = var_throw;
428         tmp_return_value = PyTuple_New(2); 292         tmp_return_value = PyTuple_New(2);
429         PyTuple_SET_ITEM0(tmp_return_value, 0, tmp_tuple_element_1); 293         PyTuple_SET_ITEM0(tmp_return_value, 0, tmp_tuple_element_1);
n 430         CHECK_OBJECT(var_exc); n
431         tmp_tuple_element_1 = var_exc; 294         tmp_tuple_element_1 = PyExc_GeneratorExit;
432         PyTuple_SET_ITEM0(tmp_return_value, 1, tmp_tuple_element_1); 295         PyTuple_SET_ITEM0(tmp_return_value, 1, tmp_tuple_element_1);
433         goto try_return_handler_2; 296         goto try_return_handler_2;
434     } 297     }
435     NUITKA_CANNOT_GET_HERE("tried codes exits in all cases"); 298     NUITKA_CANNOT_GET_HERE("tried codes exits in all cases");
436     return NULL; 299     return NULL;
440     Py_DECREF(var_gen); 303     Py_DECREF(var_gen);
441     var_gen = NULL; 304     var_gen = NULL;
442     CHECK_OBJECT(var_throw); 305     CHECK_OBJECT(var_throw);
443     Py_DECREF(var_throw); 306     Py_DECREF(var_throw);
444     var_throw = NULL; 307     var_throw = NULL;
n 445     CHECK_OBJECT(var_exc); n
446     Py_DECREF(var_exc);
447     var_exc = NULL;
448     goto function_return_exit; 308     goto function_return_exit;
449     // Exception handler code: 309     // Exception handler code:
450     try_except_handler_2:; 310     try_except_handler_2:;
n 451     exception_keeper_type_3 = exception_type; n 311     exception_keeper_type_1 = exception_type;
452     exception_keeper_value_3 = exception_value; 312     exception_keeper_value_1 = exception_value;
453     exception_keeper_tb_3 = exception_tb; 313     exception_keeper_tb_1 = exception_tb;
454     exception_keeper_lineno_3 = exception_lineno; 314     exception_keeper_lineno_1 = exception_lineno;
455     exception_type = NULL; 315     exception_type = NULL;
456     exception_value = NULL; 316     exception_value = NULL;
457     exception_tb = NULL; 317     exception_tb = NULL;
458     exception_lineno = 0; 318     exception_lineno = 0;
459 319
460     CHECK_OBJECT(var_gen); 320     CHECK_OBJECT(var_gen);
461     Py_DECREF(var_gen); 321     Py_DECREF(var_gen);
462     var_gen = NULL; 322     var_gen = NULL;
n 463     Py_XDECREF(var_throw); n
464     var_throw = NULL;
465     Py_XDECREF(var_exc);
466     var_exc = NULL;
467     // Re-raise. 323     // Re-raise.
t 468     exception_type = exception_keeper_type_3; t 324     exception_type = exception_keeper_type_1;
469     exception_value = exception_keeper_value_3; 325     exception_value = exception_keeper_value_1;
470     exception_tb = exception_keeper_tb_3; 326     exception_tb = exception_keeper_tb_1;
471     exception_lineno = exception_keeper_lineno_3; 327     exception_lineno = exception_keeper_lineno_1;
472 328
473     goto function_exception_exit; 329     goto function_exception_exit;
474     // End of try: 330     // End of try:
475 331
476     NUITKA_CANNOT_GET_HERE("Return statement must have exited already."); 332     NUITKA_CANNOT_GET_HERE("Return statement must have exited already.");