Могут ли комментарии замедлять интерпретируемый язык?

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

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

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

Ответ 1

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

Ответ 2

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

Ответ 3

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

Ответ 4

Разработал script как 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

Ответ 5

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

For N = 1 To 100000: Next

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

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

Ответ 6

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

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

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


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

Ответ 7

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

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

Ответ 8

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

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

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

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

Ответ 9

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

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

Ответ 10

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

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

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

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

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

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

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

Ответ 11

Этот вопрос действительно старый, но после прочтения принятого ответа, в котором утверждается, что он не повлияет на время выполнения, что неверно, я приведу простой пример, в котором вы можете увидеть и проверить сумму, которая действительно влияет на время выполнения.
У меня есть файл с именем 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
             ...,
            "[email protected]", # 2271]

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