评论是否会减慢解释型语言?
我问这是因为我使用Python,但它也可以适用于其他解释语言(Ruby,PHP,JavaScript)。
每当我在代码中留下评论时,我是否会放慢翻译速度? 根据我对解释器的理解有限,它以string的forms读取程序expression式,然后将这些string转换为代码。 似乎每次parsing评论,都是浪费时间。
这是这种情况吗? 在解释型语言中是否有一些用于评论的约定,或者效果可以忽略不计?
对于Python的情况,源文件在被执行之前被编译( .pyc
文件),并且在这个过程中注释被剥离。 所以,如果你有任何改动,评论可能会减慢编译时间,但是它们不会影响执行时间。
评论通常在parsing阶段或之前被剥离,parsing速度非常快,所以有效的评论不会减慢初始化时间。
那么,我写了这样一个简短的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的脚本写了一些脚本(只有大约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
按照David的评论编辑:
-*- 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
日常使用的效果是可以忽略的。 这很容易testing,但如果你考虑一个简单的循环,如:
For N = 1 To 100000: Next
你的电脑可以处理(数到10万)比你眨眼更快。 忽略以特定字符开头的文本行将快一万倍以上。
别担心。
这取决于解释器是如何实现的。 现代的大多数口译员在实际执行之前,至less对源代码进行了一些预处理,其中包括删除注释,从而不会影响到这一点。
有一段时间,当内存受到严重限制时(例如,64K的可寻址内存和用于存储的盒式磁带),你不能认为这是理所当然的。 早在Apple II,Commodore PET,TRS-80等那天,为了提高执行速度,我们相当习惯于删除评论(甚至是空白)。
当然,这也有助于这些机器具有一次只能执行一条指令的CPU,时钟速度大约为1MHz,并且只有8位处理器寄存器。 即使是现在只有在垃圾箱里才能find的机器比那些机器都快得多。
有了评论会减慢启动时间,因为脚本将被parsing成可执行的forms。 但是,在大多数情况下,注释不会减慢运行时间。
另外在python中,你可以将.py文件编译成.pyc文件,它不包含注释(我希望) – 这意味着如果脚本已经被编译,你将不会得到一个启动命令。
我对解释器的理解有限,它以string的forms读取程序expression式并将这些string转换为代码。
大多数解释器读取文本(代码)并生成抽象语法树数据结构。
该结构不包含代码,文本forms,当然也没有评论。 只要那棵树足够执行程序。 但是为了效率的原因,解释器更进一步,产生字节码。 而Python就是这样做的。
我们可以说,代码和评论,你写他们的forms,根本不存在 ,
当程序正在运行时。 所以不,评论不会在运行时减慢程序。
(*)不使用其他内部结构来表示代码以外的代码的译员,
即一个语法树,必须完成你所提到的。 在运行时反复解释代码。
正如其他答案已经说明的那样,像Python这样的现代解释语言首先parsing并将源代码编译成字节码,parsing器只是忽略注释。 这显然意味着速度的任何损失只会在启动时被实际parsing。
由于parsing器忽略注释,所以编译阶段基本上不受任何注释的影响。但注释本身中的字节实际上正被读入,然后在parsing过程中被跳过。 这意味着,如果你有大量的评论(例如数百兆字节),这会减慢口译员的速度。 但是,这又会减慢任何编译器的速度。
我想知道如何评论如何使用。 例如,三重引号是一个文档string。 如果您使用它们,则会validation内容。 我碰到一个问题,在那里我正在导入一个库到我的Python 3代码…我得到这个错误关于\ N的语法。 我看了一下行号,这是三重报价评论内容。 我有些惊讶。 新来的Python,我从来没有想过一个块评论将被解释为语法错误。
只要input:
''' (ie \Device\NPF_..) '''
Python 2不会抛出错误,但Python 3报告:SyntaxError:(unicode错误)'unicodeescape'编解码器无法解码位置14-15中的字节:格式错误\ N字符转义
所以Python 3显然是在解释三重引号,确保它是有效的语法。
但是,如果变成单行注释:#(即\ Device \ NPF_ ..)
没有错误结果。
我想知道三重报价评论是否会被单行所取代,如果能够看到绩效改变的话。