Python-Algorithmus zur Umwandlung von Ganzzahl in Zeichenfolge verwendet einen vereinfachten Algorithmus mit einer Ausführung von O (n ** 2). Wenn sich die Anzahl verdoppelt, vervierfacht sich die Wandlungszeit.
Einige einfachen Tests auf meinem Computer in Laufzeit den Anstieg zeigen:
$ time py35 -c "n=str(2**1000000)"
user 0m1.808s
$ time py35 -c "n=str(2**2000000)"
user 0m7.128s
$ time py35 -c "n=str(2**4000000)"
user 0m28.444s
$ time py35 -c "n=str(2**8000000)"
user 1m54.164s
Da der eigentliche Exponent etwa 10-mal größer als bei meinem letzten Testwert ist, sollte es etwa 100-mal länger dauern. Oder etwas mehr als 3 Stunden.
Kann es schneller gemacht werden? Ja. Es gibt mehrere Methoden, die schneller sind.
Methode 1
Es ist schneller, die sehr große Anzahl von einer Power-of-10 in zwei etwa gleich großen, aber kleineren Zahlen zu teilen. Der Prozess wird wiederholt, bis die Zahlen relativ klein sind. Dann wird str()
für jede Nummer verwendet und führende Nullen werden verwendet, um das Ergebnis auf die gleiche Länge wie die letzte Potenz von 10 zu puffern. Dann werden die Saiten verbunden, um das Endergebnis zu bilden. Diese Methode wird von der Bibliothek mpmath
verwendet und die Dokumentation legt nahe, dass sie etwa 3x schneller sein sollte.
Methode 2
ganzen Zahlen Pythons sind im binären Format gespeichert. Binär ist ideal für Berechnungen, aber Binär-zu-Dezimal-Konvertierung ist der Flaschenhals. Es ist möglich, einen eigenen Integer-Typ zu definieren, der den Wert in Blöcken von 100 Dezimalziffern (oder ähnlichen Werten) speichert. Operationen (Potenzierung, Multiplikation, Division) werden langsamer, aber die Umwandlung in eine Zeichenfolge ist sehr schnell.
Vor vielen Jahren implementierte ich eine solche Klasse und verwendete effiziente Algorithmen zur Multiplikation und Division. Der Code ist nicht mehr im Internet verfügbar, aber ich habe eine Sicherungskopie gefunden, die ich getestet habe. Die Laufzeit wurde auf ~ 14 Sekunden reduziert.
aktualisieren
ich die DecInt Code verwiesen oben aktualisiert und es ist bei https://github.com/casevh/DecInt ab sofort verfügbar.
Wenn der native Integer-Typ von Python verwendet wird, beträgt die Gesamtlaufzeit auf meinem Computer weniger als 14 Sekunden. Wenn stattdessen der Integer-Typ gmpy2
verwendet wird, beträgt die Laufzeit ~ 3,5 Sekunden.
$ py35 DecInt.py
Calculating 2^74207281
Exponentiation time: 3.236
Conversion to decimal format: 0.304
Total elapsed time: 3.540
Length of result: 22338618 digits
Methode 3
I behalten die gmpy2 Bibliothek, die für die schnelle Integer-Arithmetik einfachen Zugriff auf die GMP-Bibliothek bereitzustellen. GMP implementiert Methode 1 in hoch optimiertem C- und Assemblercode und berechnet die Primzahl und die Zeichenfolgendarstellung in ~ 5 Sekunden.
Methode 4
Das decimal
Modul in Python speichert Werte als Dezimalziffern. Jüngste Versionen von Python 3 enthalten eine C-Implementierung der dezimalen Bibliothek, die viel schneller ist als die reine Python-Implementierung mit Python 2. Die C-Implementierung läuft in etwas mehr als 3 Sekunden auf meinem Computer.
Nun, mit 100 Stellen pro Sekunde sollten Sie in etwa 6 Stunden fertig sein, so dass diese Lösung machbar scheint Vielleicht durch 1000000 auf einmal teilen und 6 Ziffern gleichzeitig bekommen? – HugoRune
Diese Lösung gibt Ihnen die Ziffern in umgekehrter Reihenfolge. –
@FrerichRaabe Danke, dass Sie mich wissen lassen, obwohl ich denke, dass es ziemlich trivial wäre, es wieder umzukehren. – Daffy