2010-04-28 9 views
57

Ich frage das, weil ich Python verwende, aber es könnte auch für andere interpretierte Sprachen gelten (Ruby, PHP, JavaScript).Verzögern Kommentare eine interpretierte Sprache?

Verlangsame ich den Interpreter, wenn ich einen Kommentar in meinem Code hinterlasse? Nach meinem begrenzten Verständnis eines Interpreters liest er Programmausdrücke als Strings und wandelt diese Strings dann in Code um. Es scheint, dass jedes Mal, wenn es einen Kommentar analysiert, das verschwendete Zeit ist.

Ist das der Fall? Gibt es eine Konvention für Kommentare in interpretierten Sprachen oder ist der Effekt vernachlässigbar?

+3

Dies war sicherlich ein Problem in BASIC auf meinem alten Commodore 64. Sprachen und Hardware haben beide seitdem dramatisch verbessert. –

+6

Sie sollten sich bewusst sein, dass der Begriff "interpretiert" nicht viel bedeutet. Python ist bytecode-kompiliert und wird nicht direkt aus der Quelle interpretiert. –

+0

Es könnte interessant sein, JavaScript in Bezug auf diese Frage zu betrachten. Ich glaube, dass JQuery zum Beispiel eine Version hat, die Kommentare und zusätzliche Leerzeichen entfernt, um die Übertragungszeit zu minimieren. –

Antwort

61

Für den Fall von Python werden Quelldateien vor der Ausführung kompiliert (die .pyc Dateien), und die Kommentare werden dabei entfernt. So Kommentare könnte verlangsamen die Compilierungszeit, wenn Sie Milliarden von ihnen haben, aber sie werden nicht die Ausführungszeit auswirken.

+18

+1, weil ich wirklich die' Gazillion' Verwendung in diesem Zusammenhang mochte –

+2

Es ist schwer vorstellbar, wie hoch der Kommentar : Code-Verhältnis müsste sein, bevor dies nachweisbar war. –

+2

@Mike: möglicherweise 1 Gazillion: 1? –

18

Kommentare werden normalerweise in oder vor dem Parsing entfernt, und das Parsen ist sehr schnell, so dass Kommentare die Initialisierungszeit nicht verlangsamen.

+10

Kommentare müssen entfernt werden, so dass sie bei ausreichend großen Kommentaren das Programm verlangsamen. Aber du musst enorme Kommentare haben (MBs? GBs?), Bevor du es überhaupt messen kannst. –

+3

Wenn Sie Megabyte an Kommentaren angeben, gibt es mehr als Megabytes an Code. Die Zeit für das tatsächliche Parsen und Kompilieren würde die "kleine" Zeit für das Auslesen von Kommentaren überfordern. – kennytm

+11

Ich ging voran und probierte das aus. Auf meinem speziellen Testsystem dauert das Parsen und Ausführen von etwa 10 MB Python-Kommentaren (und einer Zuweisungsanweisung) 349 ms. Das Verhältnis von Quellbytes zu Zeit scheint in diesem Fall ziemlich konstant zu sein, bei ungefähr 28.000 Bytes pro ms. Das gleiche Skript auf Codepad ist (wie ich mir vorgestellt habe) langsamer: http://codepad.org/Ckevfqmq – AKX

4

Der Effekt ist für den täglichen Gebrauch vernachlässigbar. Es ist einfach zu testen, aber wenn Sie eine einfache Schleife wie betrachten: kann

For N = 1 To 100000: Next 

Ihr Computer, die Verarbeitung (zählen zu 100.000) schneller, als Sie blinzeln. Das Ignorieren einer Textzeile, die mit einem bestimmten Zeichen beginnt, ist mehr als 10.000 Mal schneller.

Mach dir keine Sorgen.

1

Kommentare werden die Startzeit verlangsamen, da die Skripte in eine ausführbare Datei umgewandelt werden. In den meisten Fällen verlangsamen Kommentare die Laufzeit jedoch nicht. In Python können Sie die .py-Dateien in .pyc kompilieren, die die Kommentare nicht enthalten (ich sollte hoffen) - das bedeutet, dass Sie keinen Starttreffer bekommen werden, wenn das Skript bereits kompiliert ist .

+0

's/wird die Startzeit verlangsamen/wird die Startzeit unermesslich verlangsamen'. 's/in den meisten Fällen Kommentare nicht verlangsamen Laufzeit/in allen Fällen Kommentare nicht verlangsamen Laufzeit ' –

16

Nun, schrieb ich eine kurze Python-Programm wie folgt aus:

for i in range (1,1000000): 
    a = i*10 

Die Idee ist, eine einfache Berechnung viele Male tun.

Durch das Timing dauerte es 0,35 ± 0,01 Sekunden zu laufen.

Ich schrieb es dann mit dem Ganzen der Bibel King James wie folgt eingefügt:

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 

Diesmal dauerte es 0,4 ± 0,05 Sekunden zu laufen.

Also die Antwort ist ja. 4MB Kommentare in einer Schleife machen einen messbaren Unterschied.

+14

+1 für ein wissenschaftliches Experiment und die Bibel im selben Beitrag. 8vD –

+36

Das ist kein Kommentar. Es ist ein String-Literal. Wenn Sie sich den tatsächlichen Bytecode für Ihre zwei Codeblöcke ansehen, sehen Sie * keinen Unterschied *. Die Zeichenfolge wird einmal analysiert und ist überhaupt nicht an den Berechnungen beteiligt. Sie sollten die gleiche Verlangsamung sehen, wenn Sie die Zeichenfolge außerhalb der Schleife platzieren. –

+1

Thomas Wouters hat einen guten Punkt. Gehen Sie nun zurück und setzen Sie jede Zeile der Bibel mit '#' voran.; v) –

3

Es hängt davon ab, wie der Interpreter implementiert ist. Die meisten vernünftig modernen Interpreter machen zumindest eine kleine Vorverarbeitung des Quellcodes vor jeder tatsächlichen Ausführung, und das schließt das Entfernen der Kommentare ein, so dass sie von diesem Punkt an keinen Unterschied mehr machen.

Zu einer Zeit, als der Speicher stark eingeschränkt war (z.B., Insgesamt 64K adressierbaren Speicher und Kassetten für die Speicherung) Sie könnten solche Dinge nicht als selbstverständlich betrachten. In den Tagen des Apple II, Commodore PET, TRS-80 usw. war es ziemlich Routine, Kommentare (und sogar Leerzeichen) auszublenden, um die Ausführungsgeschwindigkeit zu verbessern.

Natürlich half es auch, dass diese Maschinen CPUs hatten, die nur jeweils einen Befehl ausführen konnten, Taktfrequenzen um 1 MHz hatten und nur 8-Bit-Prozessorregister hatten. Selbst eine Maschine jetzt nur in einer Mülltonne finden würde, ist so viel schneller als diejenigen waren, dass es nicht einmal komisch ...

1

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

Die meisten Dolmetscher den Text (Code) lesen und erzeugen Struktur, die eine abstrakte Syntaxbaumdaten .
Diese Struktur enthält keinen Code in Textform und natürlich auch keine Kommentare. Nur dieser Baum reicht aus, um Programme auszuführen. Aus Effizienzgründen gehen Interpreter jedoch einen Schritt weiter und produzieren Byte-Code. Und Python macht genau das.

Man könnte sagen, dass der Code und die Kommentare in Form man sie schrieb, sind einfach nicht vorhanden ,
, wenn das Programm ausgeführt wird. Nein, Kommentare verlangsamen die Programme nicht zur Laufzeit.

(*) Interpreter, die keine andere innere Struktur verwenden, um den Code anders als Text darzustellen,
dh ein Syntaxbaum, muss genau das tun, was Sie erwähnten. Interpretieren Sie den Code zur Laufzeit immer wieder.

5

Hat ein Skript wie Richs mit einigen Kommentaren (nur etwa 500kb Text) bis:

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

bearbeiten per David Kommentar:

-*- 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

@Nick, ich würde erwarten, dass jeder nicht-naive Interpreter nur die Kommentare für den ersten Durchlauf durch die Schleife analysiert. Haben Sie dies entweder mit einer entrollten Schleife versucht oder indem Sie zum Beispiel ein paar hundert Zeilen Kommentare in den Code eingefügt haben? –

0

Wie die anderen Antworten schon gesagt haben, analysiert eine moderne interpretierte Sprache wie Python zuerst die Quelle und kompiliert die Quelle in Bytecode, und der Parser ignoriert einfach die Kommentare. Dies bedeutet eindeutig, dass ein Geschwindigkeitsverlust nur beim Start auftritt, wenn die Quelle tatsächlich geparst wird.

Da der Parser Kommentare ignoriert, wird die Kompilierungsphase grundsätzlich nicht von den Kommentaren beeinflusst, die Sie eingeben. Die Bytes in den Kommentaren werden jedoch tatsächlich eingelesen und dann beim Parsen übersprungen. Dies bedeutet, wenn Sie eine verrückte Menge an Kommentaren haben (z. B. viele hundert Megabyte), würde dies den Interpreter verlangsamen. Aber dann würde das auch jeden Compiler verlangsamen.

+0

Ich bin mir nicht sicher, ob ich das eine "interpretierte Sprache" im strengsten Sinne des Wortes nennen würde. Etwas wie dynamisch kompiliertes oder JIT scheint passender zu sein. –

0

Ich frage mich, ob es wichtig ist, wie Kommentare verwendet werden. Zum Beispiel ist Triple-Anführungszeichen ein Docstring. Wenn Sie sie verwenden, wird der Inhalt validiert. Ich lief ein Problem in einer Weile zurück, wo ich eine Bibliothek in meinen Python 3 Code importierte ... Ich habe diesen Fehler bezüglich der Syntax auf \ N bekommen. Ich schaute auf die Zeilennummer und es war zufrieden mit einem dreifachen Zitat-Kommentar. Ich war etwas überrascht. Neu bei Python, ich hätte nie gedacht, dass ein Blockkommentar für Syntaxfehler interpretiert wird.

einfach, wenn Sie Folgendes eingeben:

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

Python 2 keinen Fehler werfen, aber Python 3 Berichte: Syntaxerror: (Unicode-Fehler) 'unicodeescape' Codec kann in Position nicht dekodieren Bytes 14- 15: missformed \ N character escape

Also interpretiert Python 3 offensichtlich das Tripel-Zitat und stellt sicher, dass es gültige Syntax ist.

Wenn jedoch in einer einzigen Zeile Kommentar gedreht: # (d \ Device \ NPF_ ..)
keine Fehler auf.

Ich frage mich, ob die dreifachen Zitat Kommentare wurden mit einzelnen Zeilen ersetzt, wenn eine Leistungsänderung gesehen werden würde.

Verwandte Themen