2012-04-26 22 views
10

Ich arbeite an einem Projekt (in Scala), wo ich einige sehr große Zahlen manipulieren muss; viel zu groß, um von den integralen Typen dargestellt zu werden. Java stellt die Klassen BigInteger und BigDecimal zur Verfügung (und scala bietet einen schönen, dünnen Wrapper um sie herum). Ich habe jedoch festgestellt, dass diese Bibliotheken wesentlich langsamer sind als andere Bibliotheken mit beliebiger Genauigkeit, die ich in der Vergangenheit verwendet habe (d. H. http://www.ginac.de/CLN/), und der Geschwindigkeitsunterschied scheint größer zu sein, als der Sprache alleine zugeschrieben werden kann.JVM Arbitrary Precision Libraries

Ich habe einige Profiling meines Programms, und 44% der Ausführungszeit wird in der BigInteger-Multiplikationsmethode ausgegeben. Ich möchte mein Programm ein wenig beschleunigen, also suche ich nach einer schnelleren und effizienteren Option als die BigInteger-Klasse (und ihre Scala-Wrapper). Ich habe LargeInteger (von JScience) und Aint (von Afloat) angeschaut. Beide scheinen jedoch langsamer zu arbeiten als die Standardklasse BigInteger.

Kennt jemand eine Java (oder auf der JVM verfügbar) arbiträre Präzisions-Math-Bibliothek mit einem Fokus auf Hochleistungs-Integer Multiplikation und Addition?

+0

Es scheint ein paar gute Erfahrung hier http://stackoverflow.com/questions/277309/java-floating-point-high-precision-library – thoredge

+0

Dank zu sein. Allerdings habe ich diese Frage gesehen und habe sowohl die JScience- als auch die AFloat-Bibliotheken ausprobiert (die, wie gesagt, langsamer zu sein scheinen als BigInteger). Das kann daran liegen, dass meine Nummern in der Dämmerungszone liegen (~ 1500 Ziffern). Wie auch immer, ich weiß, dass die Operationen viel schneller sein können (wie der C++ Code dies erreicht hat). Neben dem Sprachunterschied könnte auch die Veränderlichkeit (im Gegensatz zu den unveränderlichen Java-Impls) eine Rolle spielen. – nomad

Antwort

1

Leider, ich denke, Sie haben Pech für eine Java-native Bibliothek. Ich habe keinen gefunden. Ich empfehle die Verwendung von JNI mit GMP, das über eine ausgezeichnete willkürliche Genauigkeit verfügt. Es gibt JNI-Overhead, aber wenn Sie im Bereich von 1500 Zeichen sind, sollte das verglichen mit dem Unterschied in der algorithmischen Komplexität klein sein. Sie können verschiedene Umhüllungen von GMP für Java finden (ich glaube, das populärste ist here).

+0

Danke Rex. Ich werde diese Antwort akzeptieren b/c es scheint Ton. Es scheint jedoch, dass b/c ich eine so große Anzahl von großen Ganzzahlen erzeuge, dass der JNI-Overhead und die JVM/native Objektzuordnung mich hier wirklich umbringt; was zu einer schlechteren Leistung als die von Java's BigInteger führt. – nomad

+0

@nomad - Sie müssen die Ganzzahlen wiederverwenden. GMP kann dies tun, und Scala kann Ihnen Aktualisierungs- und Return-Links-Argument-Operationen geben, die das Wiederverwendungsproblem etwas erleichtern können. Sehen Sie sich das "Pidigits" Scala-Programm an, das GMP im Computer Languages ​​Benchmark Game verwendet, um eine Idee zu bekommen, wie dies zu tun ist. (Ich behaupte nicht, dass dies das eleganteste ist, aber es ist zumindest etwas praktikabel.) –

2

Ich bin ein bisschen spät ... Nun, ich kenne nur die Apfloat-Bibliothek, die in C++ und Java verfügbar ist. Apfloat-Library: