私はPythonを使用しているのでこれを求めていますが、他のインタプリタ言語(Ruby、PHP、JavaScript)にも適用できます。
コードにコメントを残すたびに、インタープリターの速度が低下しますか?通訳者についての私の限られた理解によれば、それはプログラム式を文字列として読み取り、それらの文字列をコードに変換します。コメントを解析するたびに、それは無駄な時間のようです。
これは本当ですか?通訳言語でのコメントに関する慣習はありますか、それともその影響はごくわずかですか?
私は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のコメントは、測定可能な違いをもたらします。
コメントは通常、解析段階またはその前に削除され、解析は非常に高速であるため、コメントによって初期化時間が遅くなることはありません。
日常の使用ではその影響はごくわずかです。テストは簡単ですが、次のような単純なループを検討する場合:
For N = 1 To 100000: Next
あなたのコンピュータはあなたが瞬きするよりも速くそれを処理することができます(100,000まで数えます)。特定の文字で始まるテキスト行を無視すると、10,000倍以上高速になります。
ご心配なく。
いくつかのコメント(約500kbのテキストのみ)を使用してRichのようなスクリプトを作成しました:
# -*- 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
インタプリタの実装方法によって異なります。最も合理的な最新のインタープリターは、実際に実行する前にソースコードに対して少なくとも少し前処理を行います。これには、コメントを削除して、それ以降の違いがないようにすることが含まれます。
かつて、メモリが厳しく制限されていたとき(たとえば、合計64Kのアドレス可能なメモリ、およびストレージ用のカセットテープ)、そのようなことを当然のことと考えることはできませんでした。Apple II、Commodore PET、TRS-80などの時代には、実行速度を向上させるために、プログラマーがコメント(さらには空白)を明示的に削除することはかなり日常的でした。これは、当時日常的に使用されていた多くのソースコードレベルのハッキングの1つにすぎませんでした1。
もちろん、これらのマシンには、一度に1つの命令しか実行できないCPUがあり、クロック速度は約1 MHzで、8ビットのプロセッサレジスタしかないことも役立ちました。今ではごみ容器でしか見つけられないマシンでさえ、それらよりもはるかに高速であるため、面白くもありません...
1.別の例として、Applesoftでは、行の番号付け方法に応じて、速度が多少向上または低下する可能性があります。メモリが機能する場合、速度の向上は、gotoステートメントのターゲットが16の倍数である場合でした。
インタプリタについての私の限られた理解は、プログラム式を文字列として読み込み、それらの文字列をコードに変換することです。
ほとんどのインタプリタは、ファイル内のテキスト(コード)を読み取り、抽象構文ツリーのデータ構造を生成します。これは、コンパイルの次の段階で簡単に読み取ることができるためです。その構造には、テキスト形式のコードは含まれていません。もちろん、コメントも含まれていません。プログラムを実行するには、そのツリーだけで十分です。しかし、通訳者は、効率上の理由から、さらに一歩進んでバイトコードを生成します。そしてPythonはまさにそれを行います。
プログラムの実行中は、コードとコメントは、あなたが書いた形式では、単に存在しないと言えます。
したがって、コメントによって実行時にプログラムの速度が低下することはありません。
注:テキスト以外のコードを表すために他の内部構造を使用しないインタープリター、
つまり構文ツリーは、あなたが述べたことを正確に実行する必要があります。実行時にコードを何度も解釈します。
コメントがあると、スクリプトが実行可能形式に解析されるため、起動時間が遅くなります。ただし、ほとんどの場合、コメントによって実行時間が遅くなることはありません。
さらに、Pythonでは、.pyファイルを.pycにコンパイルできます。これには、コメントが含まれていません(これは、スクリプトが既にコンパイルされている場合でも、スタートアップヒットが発生しないことを意味します)。
他の回答がすでに述べているように、Pythonのような最新のインタプリタ言語は、最初にソースを解析してバイトコードにコンパイルし、パーサーは単にコメントを無視します。これは明らかに、速度の低下は、ソースが実際に解析される起動時にのみ発生することを意味します。
パーサーはコメントを無視するため、コンパイルフェーズは基本的に、入力したコメントの影響を受けません。ただし、コメント自体のバイトは実際に読み込まれ、解析中にスキップされます。つまり、コメントの数が非常に多い場合(たとえば、数百メガバイト)、インタプリタの速度が低下します。しかし、これもコンパイラの速度を低下させます。
コメントの使い方が重要なのかしら。たとえば、三重引用符はdocstringです。それらを使用すると、コンテンツが検証されます。しばらく前に、ライブラリをPython3コードにインポートしていたときに問題が発生しました...\Nの構文に関してこのエラーが発生しました。行番号を調べたところ、3重引用符で囲まれた内容でした。少しびっくりしました。Pythonは初めてですが、ブロックコメントが構文エラーとして解釈されるとは思っていませんでした。
次のように入力するだけです。
'''
(i.e. \Device\NPF_..)
'''
Python 2はエラーをスローしませんが、Python3は次のように報告します。SyntaxError:(unicodeエラー)'unicodeescape'コーデックは位置14-15のバイトをデコードできません:不正な形式の\N文字エスケープ
したがって、Python 3は明らかに三重引用符を解釈し、それが有効な構文であることを確認しています。
ただし、1行のコメントに変換した場合:#(つまり、\ Device \ NPF _ ..)
エラーは発生しません。
パフォーマンスの変化が見られる場合、三重引用符のコメントが1行に置き換えられるのではないかと思います。
この質問は本当に古いですが、実行時間に影響を与えないと主張する受け入れられた回答を読んだ後、それは間違っています。実際に実行時間に影響を与える量を確認して確認できる簡単な例を示します。
というファイルがありますconstants.py
。リストには、チェスのさまざまなアクションがすべて含まれています。
LABELS = [ "a1b1"
"a1c1",
"a1d1",
"a1e1",
"a1f1",....]
リストLABELS
には2272個の要素が含まれています。私が呼ぶ別のファイルで:
import constants
np.array(constants.LABELS)
私はそれを10回測定し、コードの実行には約0.597ミリ秒かかります。ここで、ファイルを変更し、各要素の横にコメントを挿入しました(2272回)。
LABELS = [ "a1b1", # 0
"a1c1", # 1
"a1d1", # 2
"a1e1", # 3
"a1f1", # 4
...,
"Q@h8", # 2271]
実行時間を10回測定した後np.array(constants.LABELS)
、平均実行時間は4.28ミリ秒であるため、約7倍遅くなります。
したがって、コメントが多い場合は、実行時間に影響します。