2010-04-28 4 views
57

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

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

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

+3

Это, безусловно, проблема в BASIC на моем старом Commodore 64. Языки и аппаратные средства значительно улучшились с тех пор. –

+6

Вы должны знать, что термин «интерпретируемый» не означает многого. Python скомпилирован по байт-коду и не интерпретируется непосредственно из источника. –

+0

Возможно, было бы интересно рассмотреть JavaScript по этому вопросу. Я считаю, что JQuery, например, имеет версию, которая лишена комментариев и дополнительных пробелов, чтобы минимизировать время передачи. –

ответ

61

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

+18

+1, потому что мне очень понравилось использование gazillion в этом контексте –

+2

Трудно представить, насколько высок комментарий : коэффициент отношения должен был быть до того, как это было обнаружено. –

+2

@Mike: возможно 1 gazillion: 1? –

18

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

+10

Комментарии должны быть удалены, поэтому с достаточно большими комментариями они замедлят программу. Но у вас должны быть огромные комментарии (MBs? GBs?), Прежде чем вы сможете даже измерить их. –

+3

Имея мегабайты комментариев, есть более мегабайт кода. Время для фактического синтаксического анализа и компиляции будет подавлять «малое» время затухания комментариев. – kennytm

+11

Я пошел вперед и попробовал это. В моей конкретной системе тестирования синтаксический анализ и выполнение около 10 мегабайт комментариев Python (и одного оператора присваивания) занимает 349 мс. Отношение байтов источника к времени в этом случае, по-видимому, довольно постоянное: около 28 000 байт за мс. Тот же сценарий на Codepad (как я думал) медленнее: http://codepad.org/Ckevfqmq – AKX

4

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

For N = 1 To 100000: Next 

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

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

1

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

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

+0

's/замедлит время запуска/будет замедлять время запуска неизмеримо'. 's/в большинстве случаев комментарии не замедляют время выполнения/во всех случаях комментарии не замедляют время выполнения' –

16

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

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

+14

+1 для научного эксперимента и Библии в том же посте. 8vD –

+36

Это не комментарий. Это строковый литерал. Кроме того, если вы посмотрите на фактический байт-код для двух блоков кода, вы увидите * без разницы *. Строка анализируется один раз и вообще не участвует в вычислениях. Вы должны увидеть такое же замедление, если вы поместите строку за пределы цикла. –

+1

Томас Уутерс имеет хороший момент. Теперь вернитесь и префикс каждой строки Библии «#».; v) –

3

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

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

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

1

My limited understanding of an interpreter is that it reads program expressions in as strings and converts those strings into code.

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

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

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

5

ли до такой скрипт Рича с некоторыми комментариями (только около 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 
+0

@ Ник, я бы ожидал, что любой не-наивный интерпретатор будет разбирать комментарии только для первого прохода через цикл. Вы пробовали это либо с развернутым циклом, либо, скажем, вставив в код пару сотен строк комментариев? –

0

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

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

+0

Я не уверен, что я назвал бы это «интерпретированным языком» в строгом смысле этого слова. Что-то вроде динамически скомпилированного или JIT кажется более подходящим. –

0

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

Просто если вы печатаете:

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

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

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

Однако, если он обращен в одну строку комментария: # (т. Е. \ Устройство \ NPF_ ..)
Нет ошибок.

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

Смежные вопросы