Warum dauert IDLE 3.4 so lange auf diesem Programm?

9

EDIT: Ich wiederhole die Frage vollständig. Das Problem hat nichts mit time.time ()

zu tun

Hier ist ein Programm:

%Vor%

Dieses Programm, wenn es als Datei gespeichert und mit IDLE in Python 3.4 ausgeführt wird, dauert ungefähr 10 Sekunden, obwohl 0.0 von time.time() ausgedruckt wird. Das Problem ist sehr klar mit IDLE, denn wenn es über die Befehlszeile ausgeführt wird, benötigt dieses Programm fast keine Zeit.

Ein anderes Programm mit dem gleichen Effekt, wie es von senshin gefunden wurde, ist:

%Vor%

Ich habe bestätigt, dass das gleiche Programm, wenn es in Python 2.7 IDLE oder von der Befehlszeile auf Python 2.7 oder 3.4 ausgeführt wird, fast augenblicklich ist.

Was macht Python 3.4 IDLE so lange? Ich verstehe, dass das Berechnen dieser Zahl und das Speichern in den Speicher diskintensiv ist, aber was ich gerne wissen möchte, ist, warum Python 3.4 IDLE diese Berechnung durchführt und schreibt, wenn Python 2.7 IDLE und die Befehlszeile Python vermutlich nicht.

    
isaacg 14.06.2014, 04:47
quelle

2 Antworten

1

Ich würde diese Linie betrachten und sie auseinander nehmen. Sie haben:

9 << (1 << 26)

(1 << 26) ist der erste ausgewertete Ausdruck und erzeugt eine wirklich große Zahl. Was diese Zeile sagt, ist, dass Sie die Zahl 1 mit 2 auf die Potenz von 26 multiplizieren und so die Zahl 2 ** 26 im Speicher erzeugen. Dies ist jedoch nicht das Problem. Dann schiebst du 9 um die Zahl 2 ** 26 nach links. Das ergibt eine Zahl, die 50 Millionen Stellen im Speicher hat (ich kann es nicht einmal genau berechnen!), Weil die Verschiebung links einfach zu groß ist. Seien Sie vorsichtig in der Zukunft, da Verschiebungen von scheinbar kleinen Mengen tatsächlich sehr schnell wachsen. Wenn es größer war, hat Ihr Programm möglicherweise überhaupt nicht ausgeführt. Ihr Ausdruck wird mathematisch zu 9 * 2 ** (2 ** 26) ausgewertet, wenn Sie neugierig waren.

Die Mehrdeutigkeit im Kommentarteil beschäftigt sich wahrscheinlich damit, wie dieser riesige Teil des Speichers von Python unter der Haube und nicht von IDLE gehandhabt wird.

EDIT 1:

Ich achte darauf, dass ein mathematischer Ausdruck seine Antwort auswertet, selbst wenn er in einer Funktion platziert wird, die noch nicht aufgerufen wurde, nur, wenn der Ausdruck autark ist . Dies bedeutet, dass, wenn eine Variable in der Gleichung verwendet wird, die Gleichung im Byte-Code unberührt bleibt und erst bei harter Ausführung ausgewertet wird. Die Funktion muss interpretiert werden, und in diesem Prozess denke ich, dass Ihr Wert tatsächlich berechnet wird, was zu langsameren Zeiten führt. Ich bin mir nicht sicher, aber ich vermute stark, dass dieses Verhalten die Ursache ist. Auch wenn es nicht so ist, muss man zugeben, dass 9<<(1<<26) den Computer im Hintern startet, da gibt es nicht viel Optimierung, die man dort machen kann.

%Vor%

Es gibt jedoch eine leichte Täuschung bei dieser Art von Tests. Wenn ich dies mit der regulären Zeitmessung versuchte, bekam ich:

%Vor%

Denken Sie auch daran, dass das Drucken des Werts nicht möglich ist, also etwa wie folgt:

In[102]: 9<<(1<<26)

sollte nicht einmal versucht werden.

Für noch mehr Unterstützung:

Ich fühlte mich wie ein Rebell, also beschloss ich zu sehen, was passieren würde, wenn ich die rohe Ausführung der Gleichung zeitlich verändern würde:

%Vor%

Das ist wirklich fischig, weil diese Berechnung anscheinend schneller geschieht als die Zeit, die Python benötigt, um eine leere Funktion aufzurufen, was offensichtlich nicht der Fall ist. Ich wiederhole, dies ist nicht augenblicklich, sondern hat wahrscheinlich etwas damit zu tun, ein bereits berechnetes Objekt irgendwo im Speicher abzurufen und diesen Wert zu berechnen zu verwenden. Wie auch immer, nette Frage.

    
Nick Pandolfi 16.06.2014, 16:46
quelle
0

Ich bin wirklich verwirrt. Hier sind mehr Ergebnisse mit 3.4.1. Das Ausführen einer der beiden ersten Zeilen aus dem Editor in 3.4.1 oder 3.3.5 ergibt den gleichen Kontrast.

%Vor%

Der Unterschied zwischen normaler Ausführung und Idle's besteht darin, dass der Idle-Exec-Code in einem Exec-Aufruf wie oben ist, außer dass die an exec übergebenen "Globals" nicht globals () sind, sondern ein dict, das so konfiguriert ist, dass es wie globals aussieht (). Ich kenne keinen 2,7 - 3,4 - Unterschied im Leerlauf in dieser Hinsicht, außer für die Änderung von exec von Anweisung zu Funktion. Wie kann ein Exec schneller als ein Exec sein? Wie kann das Hinzufügen einer Zwischenbindung schneller sein?

    
Terry Jan Reedy 15.09.2014 09:03
quelle

Tags und Links