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

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

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

Это тот случай? Существует ли какое-либо соглашение для комментариев на интерпретируемых языках или эффект незначителен?

10 ответов

Решение

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

Ну, я написал короткую программу на 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 секунды.

Так что ответ - да.4 МБ комментариев в цикле дают ощутимую разницу.

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

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

For N = 1 To 100000: Next

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

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

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

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

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


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

Сделал скрипт вроде Rich's с некоторыми комментариями (только около 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

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

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

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

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

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

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

Этот вопрос действительно старый, но после прочтения принятого ответа, в котором утверждается, что он не повлияет на время выполнения, что неверно, я даю вам простой пример, где вы можете увидеть и проверить, насколько он действительно влияет на время выполнения.
У меня есть файл под названиемconstants.py. Он содержит все различные действия в шахматах в виде списка:

LABELS = [ "a1b1"
    "a1c1", 
    "a1d1", 
    "a1e1", 
    "a1f1",....]

Список LABELSсодержит 2272 элемента. В другом файле я вызываю:

import constants
np.array(constants.LABELS)

Я измерил его десять раз, и выполнение кода занимает около 0,597 мс. Теперь я изменил файл и вставил рядом с каждым элементом (2272 раза) комментарий:

LABELS = [ "a1b1",  # 0 
            "a1c1", # 1
            "a1d1", # 2
            "a1e1", # 3
            "a1f1", # 4
             ...,
            "Q@h8", # 2271]

Теперь, после измерения времени выполнения np.array(constants.LABELS)десять раз у меня среднее время выполнения 4,28 мс, то есть примерно в 7 раз медленнее.
Следовательно, да, это влияет на время выполнения, если у вас много комментариев.

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

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

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

Просто если вы наберете:

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

Python 2 не выдает ошибку, но Python 3 сообщает: SyntaxError: (ошибка Unicode) кодек "unicodeescape" не может декодировать байты в позиции 14-15: сбой с искаженным символом \ N

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

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

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

Другие вопросы по тегам