我之所以问这个,是因为我使用Python,但它也可以适用于其他解释的语言(Ruby,PHP,JavaScript)。

每当我在代码中发表评论时,我会放慢口译员吗?根据我对口译员的有限理解,它将读取程序表达式为字符串,然后将这些字符串转换为代码。似乎每次解析评论时,都会浪费时间。

是这样吗?解释性语言中是否有一些评论的惯例,或者效果可以忽略不计?

有帮助吗?

解决方案

对于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秒。

所以答案是 是的. 。循环中的4MB评论产生了可衡量的差异。

评论通常会在解析阶段或之前剥离,并且解析非常快,因此有效评论不会放慢初始化时间。

像里奇(Rich's)这样的脚本进行了一些评论(只有500kb文本):

# -*- 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倍。

不用担心。

这取决于解释器的实施方式。在任何实际执行之前,大多数合理的现代口译员至少对源代码进行了一些预处理,这将包括删除评论,因此从那时起就没有区别。

一次,当内存受到严格限制(例如,总可寻址内存和存储盒式磁带)时,您无法将类似的事情视为理所当然。早在Apple II,Commodore Pet,TRS-80等的那天,对于程序员来说,明确删除评论(甚至是白空间)以提高执行速度是相当常规的。这也是当时常规使用的众多源代码级黑客攻击之一1.

当然,这也有助于这些机器的CPU一次只能执行一个指令,时钟速度约为1 MHz,并且只有8位处理器寄存器。即使您现在只在垃圾箱中发现的机器也比那些不有趣的速度要快得多。


1.例如,在Applesoft中,您可能会根据编号的线条而获得或失去一点速度。如果内存有效,则速度增长是当goto语句的目标为16的倍数时。

发表评论会减慢启动时间,因为脚本将被解析为可执行的表单。但是,在大多数情况下,评论不会放慢运行时。

此外,在Python中,您可以将.py文件编译到.pyc中,该文件不会包含注释(我希望) - 这意味着如果已经编译了脚本,则不会受到启动点击。

我对解释器的有限理解是,它以字符串读取程序表达式,并将这些字符串转换为代码。

大多数口译员读取文本(代码)并产生抽象的语法树数据结构。
该结构以文本形式不包含代码,当然也没有评论。只是该树足以执行程序。但是,出于效率原因,口译员进一步迈出了一步并产生字节代码。 Python就是这样做的。

我们可以说,代码和评论(您写的表格)只是 不存在,
程序运行时。所以不,评论在运行时不会放慢程序。

(*)不使用其他内部结构来表示文本以外的代码的口译员
IE语法树,必须准确地做您提到的。在运行时一次又一次解释代码。

正如其他答案已经说过的那样,诸如Python首次解析的现代解释语言并将源汇编为字节码,而解析器简单地忽略了这些评论。这显然意味着只有在源实际解析时,任何速度损失都会发生在启动时。

由于解析器忽略了评论,因此编译阶段基本上不受您发表的任何评论的影响。但是评论本身中的字节实际上是在阅读中,然后在解析过程中跳过。这意味着,如果您有很多评论(例如数百兆字节),那将减慢口译员。但是,这也将减慢任何编译器。

我想知道如何使用评论是否重要。例如,三引号是docstring。如果您使用它们,则将验证内容。我遇到了一个问题,我将图书馆导入到我的Python 3代码中...我在 n上遇到了有关语法的错误。我查看了行号,它在三重报价评论中满足。我有些惊讶。 Python的新手,我从没想过会为语法错误解释块评论。

如果您输入:

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

Python 2不会丢失错误,但是Python 3报告:SyntaxError :( Unicode错误)'Unicodeescape'编解码器无法在位置14-15中解释字节:畸形 n字符逃跑

因此,Python 3显然正在解释三重报价,确保它是有效的语法。

但是,如果变成单行注释:#(即 device npf_ ..)
没有错误结果。

我想知道是否会看到表演更改的三重报价评论是否被单行替换。

这个问题确实很旧,但是在阅读了接受的答案之后,该答案声称它不会影响执行时间,这是错误的,我为您提供了一个简单的示例,您可以在其中看到并检查其确实会影响执行时间的数量。
我有一个叫做的文件 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倍。
因此,是的,如果您有很多评论,它会影响执行时间。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top