Ich erstelle einen Komparator, der mehrspaltige Sortierfunktionen für eine begrenzte Zeichenfolge bietet. Ich verwende derzeit die Split-Methode aus der String-Klasse als meine bevorzugte Wahl für die Aufteilung des rohen Strings in Token.
Ist dies die leistungsstärkste Methode, um den rohen String in ein String-Array zu konvertieren? Ich werde Millionen von Zeilen sortieren, also denke ich, dass der Ansatz wichtig ist.
Es scheint gut zu laufen und ist sehr einfach, aber unsicher, ob es in Java einen schnelleren Weg gibt.
So funktioniert die Sortierung in meinem Komparator:
public int compare(String a, String b) {
String[] aValues = a.split(_delimiter, _columnComparators.length);
String[] bValues = b.split(_delimiter, _columnComparators.length);
int result = 0;
for( int index : _sortColumnIndices ) {
result = _columnComparators[index].compare(aValues[index], bValues[index]);
if(result != 0){
break;
}
}
return result;
}
Nach dem Benchmarking der verschiedenen Ansätze, ob Sie es glauben oder nicht, war die Split-Methode mit der neuesten Version von Java die schnellste. Sie können meinen fertigen Komparator hier herunterladen: https://sourceforge.net/projects/multicolumnrowcomparator/
quelle
StringUtils.split[PreserveAllTokens](text, delimiter)
.Antworten:
Ich habe dafür einen schnellen und schmutzigen Benchmark-Test geschrieben. Es werden 7 verschiedene Methoden verglichen, von denen einige spezifische Kenntnisse der zu teilenden Daten erfordern.
Für die allgemeine allgemeine Aufteilung ist Guava Splitter 3,5-mal schneller als String # split (), und ich würde empfehlen, dies zu verwenden. Stringtokenizer ist etwas schneller und das Aufteilen mit indexOf ist doppelt so schnell wie wieder.
Für den Code und weitere Informationen siehe http://demeranville.com/battle-of-the-tokenizers-delimited-text-parser-performance/
quelle
Wie @Tom schreibt, ist ein Ansatz vom Typ indexOf schneller als
String.split()
, da letzterer reguläre Ausdrücke behandelt und viel zusätzlichen Aufwand für sie hat.Eine Änderung des Algorithmus kann jedoch zu einer erheblichen Beschleunigung führen. Angenommen, dieser Komparator wird zum Sortieren Ihrer ~ 100.000 Zeichenfolgen verwendet, schreiben Sie die nicht
Comparator<String>
. Denn im Laufe Ihrer Art, wird die gleiche String wahrscheinlich verglichen werden mehrere Male, so werden Sie es aufgeteilt mehrere Male, etc ...Teilen Sie alle Strings einmal in String [] und
Comparator<String[]>
sortieren Sie den String []. Am Ende können Sie sie dann alle miteinander kombinieren.Alternativ können Sie auch eine Map verwenden, um den String -> String [] zwischenzuspeichern oder umgekehrt. zB (skizzenhaft) Beachten Sie auch, dass Sie Speicher gegen Geschwindigkeit eintauschen und hoffen, dass Sie viel RAM haben
quelle
sortAndSave()
Aufrufs Ihren Cache geleert haben. Dann sollte Ihnen aufgrund eines riesigen Caches nicht der Speicher ausgehen. IMO sollte der Code einige zusätzliche Hooks enthalten, z. B. das Auslösen von Ereignissen oder das Aufrufen von Do-Nothing-geschützten Methoden, die Benutzer wie Sie überschreiben könnten. (Außerdem sollten nicht alle statischen Methoden vorhanden sein, damit sie dies tun können.) Möglicherweise möchten Sie die Autoren kontaktieren und eine Anfrage einreichen.Gemäß diesen Benchmarks ist StringTokenizer schneller zum Teilen von Zeichenfolgen, gibt jedoch kein Array zurück, was es weniger bequem macht.
Wenn Sie Millionen von Zeilen sortieren müssen, würde ich die Verwendung eines RDBMS empfehlen.
quelle
Dies ist die Methode, die ich zum Parsen großer (1 GB +) tabulatorgetrennter Dateien verwende. Es hat weit weniger Overhead als
String.split()
, ist aberchar
als Trennzeichen beschränkt. Wenn jemand eine schnellere Methode hat, würde ich sie gerne sehen. Dies kann auch überCharSequence
und erfolgenCharSequence.subSequence
, erfordert jedoch eine ImplementierungCharSequence.indexOf(char)
(String.indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex)
bei Interesse siehe Paketmethode ).quelle