Замедляют ли комментарии интерпретируемый язык?

Я спрашиваю это, потому что я использую Python, но он может применяться и к другим интерпретируемым языкам (Ruby, PHP, JavaScript).

я замедляю интерпретатор всякий раз, когда я оставляю комментарий в своем коде? Согласно моему ограниченному пониманию интерпретатора, он читает выражения программы в виде строк, а затем преобразует эти строки в код. Кажется, что каждый раз, когда он анализирует комментарий, это потерянное время.

это дело? Есть некоторые конвенции комментарии на интерпретируемых языках, или эффект незначителен?

10 ответов


для случая Python исходные файлы компилируются перед выполнением (.pyc files), и комментарии удаляются в процессе. Так что комментарии может замедлить время компиляции, если у вас есть gazillions из них, но они не влияют на время выполнения.


Ну, я написал короткую программу python, как это:

for i in range (1,1000000):
    a = i*10

идея в том, чтобы сделать простой расчет нагрузок раз.

по времени это заняло 0,35±0,01 секунды для запуска.

затем я переписал его со всей Библией короля Иакова, вставленной следующим образом:

for i in range (1,1000000):
    """
The Old Testament of the King James Version of the Bible

The First Book of Moses:  Called Genesis


1:1 In the beginning God created the heaven and the earth.

1:2 And the earth was without form, and void; and darkness was upon
the face of the deep. And the Spirit of God moved upon the face of the
waters.

1:3 And God said, Let there be light: and there was light.

...
...
...
...

Even so, come, Lord Jesus.

22:21 The grace of our Lord Jesus Christ be with you all. Amen.
    """
    a = i*10

на этот раз для запуска потребовалось 0,4±0,05 секунды.

таким образом, ответ да. 4MB комментариев в цикле делают измеримую разницу.


комментарии обычно удаляются в или перед этапом синтаксического анализа, а синтаксический анализ очень быстрый, поэтому эффективно комментарии не замедляют время инициализации.


сделал сценарий, как у Рича, с некоторыми комментариями (только текст около 500 Кб):

# -*- coding: iso-8859-15 -*-
import timeit

no_comments = """
a = 30
b = 40
for i in range(10):
    c = a**i * b**i
"""
yes_comment = """
a = 30
b = 40

# full HTML from http://en.wikipedia.org/
# wiki/Line_of_succession_to_the_British_throne

for i in range(10):
    c = a**i * b**i
"""
loopcomment = """
a = 30
b = 40

for i in range(10):
    # full HTML from http://en.wikipedia.org/
    # wiki/Line_of_succession_to_the_British_throne

    c = a**i * b**i
"""

t_n = timeit.Timer(stmt=no_comments)
t_y = timeit.Timer(stmt=yes_comment)
t_l = timeit.Timer(stmt=loopcomment)

print "Uncommented block takes %.2f usec/pass" % (
    1e6 * t_n.timeit(number=100000)/1e5)
print "Commented block takes %.2f usec/pass" % (
    1e6 * t_y.timeit(number=100000)/1e5)
print "Commented block (in loop) takes %.2f usec/pass" % (
    1e6 * t_l.timeit(number=100000)/1e5)


C:\Scripts>timecomment.py
Uncommented block takes 15.44 usec/pass
Commented block takes 15.38 usec/pass
Commented block (in loop) takes 15.57 usec/pass

C:\Scripts>timecomment.py
Uncommented block takes 15.10 usec/pass
Commented block takes 14.99 usec/pass
Commented block (in loop) takes 14.95 usec/pass

C:\Scripts>timecomment.py
Uncommented block takes 15.52 usec/pass
Commented block takes 15.42 usec/pass
Commented block (in loop) takes 15.45 usec/pass

редактировать в соответствии с комментарием Дэвида:

 -*- coding: iso-8859-15 -*-
import timeit

init = "a = 30\nb = 40\n"
for_ = "for i in range(10):"
loop = "%sc = a**%s * b**%s"
historylesson = """
# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
# blah blah...
# --></body></html> 
"""
tabhistorylesson = """
    # <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    # blah blah...
    # --></body></html> 
"""

s_looped = init + "\n" + for_ + "\n" + tabhistorylesson + loop % ('   ','i','i')
s_unroll = init + "\n"
for i in range(10):
    s_unroll += historylesson + "\n" + loop % ('',i,i) + "\n"
t_looped = timeit.Timer(stmt=s_looped)
t_unroll = timeit.Timer(stmt=s_unroll)

print "Looped length: %i, unrolled: %i." % (len(s_looped), len(s_unroll))

print "For block takes %.2f usec/pass" % (
    1e6 * t_looped.timeit(number=100000)/1e5)
print "Unrolled it takes %.2f usec/pass" % (
    1e6 * t_unroll.timeit(number=100000)/1e5)


C:\Scripts>timecomment_unroll.py
Looped length: 623604, unrolled: 5881926.
For block takes 15.12 usec/pass
Unrolled it takes 14.21 usec/pass

C:\Scripts>timecomment_unroll.py
Looped length: 623604, unrolled: 5881926.
For block takes 15.43 usec/pass
Unrolled it takes 14.63 usec/pass

C:\Scripts>timecomment_unroll.py
Looped length: 623604, unrolled: 5881926.
For block takes 15.10 usec/pass
Unrolled it takes 14.22 usec/pass

влияние незначительно для ежедневного использования. Это легко проверить, но если вы считаете простой цикл, такой как:

For N = 1 To 100000: Next

ваш компьютер может обрабатывать это (считать до 100 000) быстрее, чем вы можете моргнуть. Игнорирование строки текста, которая начинается с определенного символа, будет более чем в 10 000 раз быстрее.

Не беспокойтесь об этом.


Это зависит от того, как реализован интерпретатор. Наиболее разумно современные интерпретаторы выполняют, по крайней мере, некоторую предварительную обработку исходного кода перед любым фактическим выполнением, и это будет включать удаление комментариев, чтобы они не имели никакого значения с этого момента.

в одно время, когда память была сильно ограничена (например, общая адресуемая память 64K и кассеты для хранения), вы не могли принимать такие вещи как должное. Назад в день Apple II, Commodore PET, TRS-80 и др. для программистов было довольно рутинно явно удалять комментарии (и даже пробелы) для повышения скорости выполнения. Это также был только один из многих хаков исходного кода уровня, обычно используемых в то время1.

конечно, это также помогло, что эти машины имели процессоры, которые могли выполнять только одну инструкцию за раз, имели тактовую частоту около 1 МГц и имели только 8-битные регистры процессора. Даже машина, которую сейчас можно найти только в мусорном контейнере, настолько быстрее, что это даже не смешно...


1. Например, в Applesoft вы можете получить или потерять немного скорости в зависимости от того, как вы пронумеровали строки. Если память служит, увеличение скорости было, когда цель оператора goto была кратна 16.


наличие комментариев замедлит время запуска, так как скрипты будут проанализированы в исполняемую форму. Однако в большинстве случаев комментарии не замедляют выполнение.

кроме того, в python вы можете скомпилировать .py файлы В.pyc, который не будет содержать комментариев (я надеюсь) - это означает, что вы не получите хит запуска, если скрипт уже скомпилирован.


мое ограниченное понимание интерпретатор заключается в том, что он читает программу выражения в виде строк и преобразования эти строки в код.

большинство интерпретаторов читают текст (код) и создают абстрактную структуру данных дерева синтаксиса.
Эта структура не содержит кода в текстовой форме и, конечно, никаких комментариев. Этого дерева достаточно для выполнения программ. Но интерпретаторы, по соображениям эффективности, идут еще дальше и производят байтовый код. И Python делает именно это.

можно сказать, что код и комментарии, в том виде, в котором вы их написали, просто нет,
когда программа запущена. Так что нет, комментарии не замедляют программы во время выполнения.

(*) интерпретаторы, которые не используют другую внутреннюю структуру для представления кода, отличного от текста,
т. е. синтаксическое дерево, должно делать именно то, что вы упомянули. Интерпретируйте код снова и снова во время выполнения.


Как уже говорилось в других ответах, современный интерпретируемый язык, такой как Python, сначала анализирует и компилирует источник в байт-код, а парсер просто игнорирует комментарии. Это явно означает, что любая потеря скорости произойдет только при запуске, когда источник фактически анализируется.

поскольку синтаксический анализатор игнорирует комментарии, фаза компиляции в основном не зависит от комментариев, которые вы вводите. Но байты в самих комментариях фактически считываются, и затем перепрыгнул во время разбора. Это означает, что если у вас есть сумасшедшее количество комментариев (например, многие сотни мегабайт), это замедлит интерпретатор. Но опять же, это замедлит любой компилятор.


интересно, имеет ли значение, как используются комментарии. Например, тройные кавычки-это docstring. Если вы используете их, содержимое проверяется. Я столкнулся с проблемой некоторое время назад, когда я импортировал библиотеку в мой код на Python 3... Я получил эту ошибку относительно синтаксиса на \N. Я посмотрел на номер строки, и он был содержимым в комментарии тройной цитаты. Я был несколько удивлен. Новый для Python, я никогда не думал, что комментарий блока будет интерпретироваться для синтаксических ошибок.

просто если ввести:

'''
(i.e. \Device\NPF_..)
'''

Python 2 не выдает ошибку, но отчеты Python 3: SyntaxError: (ошибка unicode) кодек 'unicodeescape' не может декодировать байты в позиции 14-15: malformed \N character escape

таким образом, Python 3, очевидно, интерпретирует тройную цитату, убеждаясь, что это правильный синтаксис.

однако, если превратить в однострочный комментарий: # (т. е. \Device\NPF_..)
Нет результатов ошибок.

интересно, если тройная цитата комментарии wer заменено на одиночные строки, если изменение производительности будет замечено.