Замедляют ли комментарии интерпретируемый язык? - PullRequest
63 голосов
/ 28 апреля 2010

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

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

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

Ответы [ 10 ]

76 голосов
/ 28 апреля 2010

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

23 голосов
/ 28 апреля 2010

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

19 голосов
/ 28 апреля 2010

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

5 голосов
/ 28 апреля 2010

Придумал сценарий, подобный Rich, с некоторыми комментариями (всего около 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
4 голосов
/ 28 апреля 2010

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

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

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


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

4 голосов
/ 28 апреля 2010

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

For N = 1 To 100000: Next

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

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

1 голос
/ 28 апреля 2010

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

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

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

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

1 голос
/ 28 апреля 2010

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

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

0 голосов
/ 23 сентября 2014

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

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

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

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

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

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

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

0 голосов
/ 28 апреля 2010

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

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

...