评论会减慢解释语言的速度吗?

Man*_*tis 66 python interpreter comments interpreted-language

我问这个是因为我使用Python,但它也适用于其他解释语言(Ruby,PHP,JavaScript).

每当我在代码中留下评论时,我是否会放慢口译员的速度?根据我对解释器的有限理解,它以字符串形式读取程序表达式,然后将这些字符串转换为代码.似乎每次解析评论时都会浪费时间.

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

Lup*_*uch 79

对于Python的情况,源文件在执行之前被编译(.pyc文件),并且在过程中删除了注释.因此,如果您有足够的注释,注释可能会减慢编译时间,但它们不会影响执行时间.

  • +1,因为我真的很喜欢在这种情况下使用'gazillion` (29认同)
  • @Mike:可能是1亿:1? (3认同)
  • 很难想象评论:代码比率在可检测到之前必须有多高. (2认同)

Ric*_*haw 24

好吧,我写了一个这样的短python程序:

for i in range (1,1000000):
    a = i*10
Run Code Online (Sandbox Code Playgroud)

这个想法是,做一个简单的计算次数.

通过计时,运行需要0.35±0.01秒.

然后我用这样插入的整个King James Bible重写了它:

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
Run Code Online (Sandbox Code Playgroud)

这次运行需要0.4±0.05秒.

所以答案是肯定的.循环中4MB的注释会产生可测量的差异.

  • 那不是评论.这是一个字符串文字.此外,如果您查看两个代码块的实际字节码,您将看到*没有区别*.该字符串被解析一次,根本不参与计算.如果将字符串放在循环外部,则应该看到相同的减速. (42认同)
  • 科学实验的+1和同一篇文章中的圣经.8vD (17认同)
  • 尽管有缺陷的方法,+1还是可以反击一个愚蠢的downvote,以及实际尝试的道具.TIAS(试一试)经常提供比抽象讨论更好的答案. (11认同)
  • @David,这个测试的案例不是OP所描述的,也不代表人们实际编写的任何代码. (6认同)
  • @Rich,您可以将字符串转换为注释并发布新的时间吗? (3认同)

ken*_*ytm 19

注释通常在解析阶段或之前被删除,并且解析非常快,因此有效注释不会减慢初始化时间.

  • 我继续尝试了这个.在我的特定测试系统上,解析和执行大约10兆的Python注释(和一个赋值语句)需要349毫秒.在这种情况下,源字节与时间的比率似乎是相当恒定的,大约每毫秒28,000字节.Codepad上的相同脚本(我想象的)慢了:http://codepad.org/Ckevfqmq (11认同)
  • 必须删除评论,因此如果评论足够大,它们将会减慢程序的速度.但是你甚至可以在测量它之前得到巨大的评论(MBs?GBs?). (10认同)
  • 拥有兆字节的评论意味着有超过兆字节的代码.实际解析和编译的时间将压倒"小"评论剥离时间. (3认同)

Nib*_*Pig 5

日常使用的效果可以忽略不计。测试很容易,但如果您考虑一个简单的循环,例如:

For N = 1 To 100000: Next
Run Code Online (Sandbox Code Playgroud)

您的计算机可以比您眨眼的速度更快地处理(数到 100,000)。忽略以某个字符开头的一行文本会快 10,000 倍以上。

别担心。


Jer*_*fin 5

这取决于解释器的实现方式。大多数合理的现代解释器在任何实际执行之前至少对源代码进行一些预处理,这将包括删除注释,以便从那时起它们没有区别。

曾几何时,当内存受到严重限制时(例如,64K 的总可寻址内存和用于存储的盒式磁带),您不能将这样的事情视为理所当然。在 Apple II、Commodore PET、TRS-80 等时代,程序员显式删除注释(甚至空格)以提高执行速度是相当常规的。这也是仅在时间通常采用的许多源代码级黑客的一个1

当然,这也有助于这些机器的 CPU 一次只能执行一条指令,时钟速度约为 1 MHz,并且只有 8 位处理器寄存器。即使是现在只能在垃圾箱中找到的机器也比那些机器快得多,甚至都不好笑......


1. 再举一个例子,在 Applesoft 中,根据您如何编号行,您可能会增加或减少一点速度。如果没记错的话,速度增益是当 goto 语句的目标是 16 的倍数时。


Nic*_*k T 5

像Rich这样的脚本做了一些评论(只有大约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)
Run Code Online (Sandbox Code Playgroud)


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
Run Code Online (Sandbox Code Playgroud)

根据大卫的评论编辑:

 -*- 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)
Run Code Online (Sandbox Code Playgroud)


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
Run Code Online (Sandbox Code Playgroud)