2015-05-05 16 views
7

Während mit Euler 99 experimentieren, bemerkte ich, dass diese Operationen unterschiedliche Zeit in Anspruch nehmen:Exponentialberechnung in Python

>>> 632382**518061 # never finishes.. 

>>> 632382**518061 > 519432**525806 # finishes in few seconds 
True 

Ich frage mich, was ist der Grund dafür?

+1

Als eine Nebenfrage, wenn der Python-Compiler '632382 ** 518061' sieht, denkt es," hey, einfache Operation für zwei kleinere Ganzzahl-Literale, ich werde das zur Kompilierzeit machen und es konstant falten ". Es dauert also etwa 3 Sekunden, um diese Codezeile zu kompilieren, aber nur 20 Nanosekunden, um sie auszuführen (und dann 200 Sekunden, um die zu druckende Zeichenfolge zu formatieren ...). Auf dem interaktiven Interpreter spielt das keine Rolle (es sei denn, du versuchst, Benchmark mit "timeit" zu machen), sondern lege es in ein Modul und "importiere" dieses Modul, und das erste Mal dauert 3 Sekunden, aber wenn du es nochmal machst (selbst nach dem Beenden und Relaunch) wird es nicht. – abarnert

+1

Übrigens, ich vermute, auch wenn ich das Problem 99 nicht gelesen habe, liegt es daran, Zahlen zu geben, die zu groß sind, um sie zu berechnen, also müssen Sie wissen und/oder nachschauen und einen Trick wie modulare Potenzierung oder Austeilung lernen Faktoren von jeder Seite und nur zu berechnen, wenn es keine gemeinsamen Faktoren gibt oder zu schätzen und dann zu testen, dass der Fehler reicht. – abarnert

+0

Speicher und Uhrzeit sind gefährdet, wenn Sie versuchen, eine Zahl mit vielen Ziffern wie im ersten Beispiel anzuzeigen. In der Sekunde gibt es keinen Versuch, tatsächlich anzuzeigen, nur ein einfacher Vergleich, der nicht so viel Zeit verbraucht wie das Drucken auf die Standardausgabe. –

Antwort

12

Die Sache ist Python versucht, das erste Ergebnis zu drucken. Aber diese Zahl hat eine Zillion Stellen und Python spült die Ausgabe nicht, bis eine neue Zeile angetroffen wird, nachdem alle Ziffern an die Standardausgabe gesendet wurden. Wie @abarnert bereits erwähnt hat, ist das, was oft schlimmer ist, die Zahl in eine Zeichenkette umzuwandeln, um sie zu drucken. Dies erfordert beträchtliche Speicherzuweisung und Verarbeitungsleistung. Auf der anderen Seite muss der zweite Ausdruck nur True drucken. Sie können es überprüfen, wenn Sie dem ersten Ausdruck zuweisen:

>>> a = 632382**518061 

Auf diese Weise wird die Ausgabe der Nummer unterdrückt.

+0

Ich denke, es ist mehr Formatierung der riesigen Zeichenfolge und Drucken es zur Ausgabe. Auf meiner Maschine dauert es 1,68s, um die Multiplikation zu kompilieren, 24,6ns, um das resultierende kompilierte Literal auszuwerten, 28s um 'str' it und nur 2s um' zu schreiben'. Unter Windows kann es viel länger dauern, um zu schreiben, oder in IDLE, aber auf einem ordentlichen Stand sollte es nicht der Haupt-Engpass sein. – abarnert

+0

Diese 28s ist für Python 2.7 und 3.4 ist ziemlich nah, aber in 3.2 dauert der 'str' Teil mindestens 6 Minuten; Ich gehe zu^C es jetzt ... – abarnert

+0

@abarnert Es macht Sinn, kann ich es in meiner Antwort hinzufügen? – JuniorCompressor