Есть ли разница в производительности между использованием (или нет) «еще» после «если [условие]: перерыв» внутри цикла while?

#python #if-statement #while-loop #break

Вопрос:

У меня есть цикл while, управляемый оператором if [условие]: break.

Например, смотрите следующее:

 #option 1 i=0 while(igt;=0)  if [condition]:  break  else:  [do something]  i=i 1  # option 2 i=0 while(igt;=0)  if [condition]:  break  [do something]  i=i 1  

Есть ли какая-либо разница в производительности при последующем использовании (или нет) «еще»? Есть ли какая-то причина предпочесть одно другому?

@khelwood @DeepSpace, сначала я был обеспокоен удобочитаемостью, потом у меня возникли сомнения. Моя реальная проблема немного сложнее, поэтому я привел этот пример, чтобы больше сосредоточиться на остатке «еще». В любом случае, советы по управлению циклом и удобочитаемости приветствуются.

Я последовал предложению @Barmar’а и протестировал байт-код, используя модуль dist и две функции (см. Код ниже). Для краткости я использую простое условие (igt;10) и игнорирую часть [сделать что-то].

 import dis def option1():  i = 0  while (igt;=0):  if (igt;10):  break  else:  i=i 1  return  def option2():  i = 0  while (igt;=0):  if (igt;10):  break  i=i 1  return   dis.dis(option1) dis.dis(option2)  

Я не уверен, что это имеет отношение к делу, но я заметил различия в некоторых числах двух последних столбцов.

Кроме того, существует дополнительная операция «24 JUMP_ABSOLUTE» для опции 1 (между строками 6 и 8).

 *option1:*   3 0 LOAD_CONST 1 (0)  2 STORE_FAST 0 (i)   4 4 SETUP_LOOP 32 (to 38)  gt;gt; 6 LOAD_FAST 0 (i)  8 LOAD_CONST 1 (0)  10 COMPARE_OP 5 (gt;=)  12 POP_JUMP_IF_FALSE 36   5 14 LOAD_FAST 0 (i)  16 LOAD_CONST 2 (10)  18 COMPARE_OP 4 (gt;)  20 POP_JUMP_IF_FALSE 26   6 22 BREAK_LOOP  24 JUMP_ABSOLUTE 6   8 gt;gt; 26 LOAD_FAST 0 (i)  28 LOAD_CONST 3 (1)  30 BINARY_ADD  32 STORE_FAST 0 (i)  34 JUMP_ABSOLUTE 6  gt;gt; 36 POP_BLOCK   9 gt;gt; 38 LOAD_CONST 0 (None)  40 RETURN_VALUE  *option2:*   12 0 LOAD_CONST 1 (0)  2 STORE_FAST 0 (i)   13 4 SETUP_LOOP 30 (to 36)  gt;gt; 6 LOAD_FAST 0 (i)  8 LOAD_CONST 1 (0)  10 COMPARE_OP 5 (gt;=)  12 POP_JUMP_IF_FALSE 34   14 14 LOAD_FAST 0 (i)  16 LOAD_CONST 2 (10)  18 COMPARE_OP 4 (gt;)  20 POP_JUMP_IF_FALSE 24   15 22 BREAK_LOOP   16 gt;gt; 24 LOAD_FAST 0 (i)  26 LOAD_CONST 3 (1)  28 BINARY_ADD  30 STORE_FAST 0 (i)  32 JUMP_ABSOLUTE 6  gt;gt; 34 POP_BLOCK   17 gt;gt; 36 LOAD_CONST 0 (None)  38 RETURN_VALUE  

Комментарии:

1. Существенной разницы нет, если только вы не найдете одно более читабельным, чем другое.

2. Посмотрите на сгенерированный байт-код. Я был бы удивлен, если бы была какая-то разница.

3. @khelwood С точки зрения читаемости я нахожу первый хуже второго (бесполезный уровень отступа), но оба они не самые лучшие. @minovsor Более идиоматичный способ, чем оба варианта (если вы на самом деле не используете i где-то еще в цикле), — это просто while condition: . Никакой разницы в производительности, просто гораздо более читаемый код

4. Третья альтернатива состоит в том, чтобы поместить [condition] непосредственно в while .