Buduję komparator, który umożliwia sortowanie wielu kolumn na ograniczonym łańcuchu. Obecnie używam metody split z klasy String jako preferowanego sposobu dzielenia surowego ciągu na tokeny.
Czy to jest najlepszy sposób na konwersję surowego ciągu znaków na tablicę ciągu znaków? Będę sortować miliony wierszy, więc myślę, że podejście ma znaczenie.
Wydaje się, że działa dobrze i jest bardzo łatwy, ale nie ma pewności, czy w Javie jest szybszy sposób.
Oto jak działa sortowanie w moim Komparatorze:
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;
}
Po analizie porównawczej różnych podejść, wierzcie lub nie, metoda podziału była najszybsza przy użyciu najnowszej wersji Java. Mój ukończony komparator możesz pobrać tutaj: https://sourceforge.net/projects/multicolumnrowcomparator/
java
performance
efficiency
sorting
Constantin
źródło
źródło
StringUtils.split[PreserveAllTokens](text, delimiter)
.Odpowiedzi:
Napisałem dla tego szybki i brudny test porównawczy. Porównuje 7 różnych metod, z których niektóre wymagają szczególnej wiedzy na temat dzielonych danych.
Dla podstawowego podziału ogólnego, Guava Splitter jest 3,5 razy szybszy niż String # split () i polecam go użyć. Stringtokenizer jest nieco szybszy, a dzielenie się za pomocą indexOf jest dwa razy szybsze niż ponownie.
Kod i więcej informacji można znaleźć na stronie http://demeranville.com/battle-of-the-tokenizers-delimited-text-parser-performance/
źródło
Jak pisze @Tom, podejście typu indexOf jest szybsze niż
String.split()
, ponieważ to ostatnie zajmuje się wyrażeniami regularnymi i ma dla nich wiele dodatkowych kosztów.Jednak jedna zmiana algorytmu, która może dać super przyspieszenie. Zakładając, że ten komparator będzie używany do sortowania ~ 100 000 ciągów, nie pisz
Comparator<String>
. Ponieważ w trakcie sortowania ten sam Ciąg prawdopodobnie będzie porównywany wiele razy, więc podzielisz go wiele razy itp.Podziel wszystkie ciągi raz na String [] i
Comparator<String[]>
posortuj String []. Następnie możesz połączyć je wszystkie razem.Możesz też użyć mapy do buforowania ciągu -> Ciąg [] lub odwrotnie. np. (szkicowy) Pamiętaj też, że wymieniasz pamięć na szybkość, mam nadzieję, że masz dużo pamięci RAM
źródło
sortAndSave()
połączenia, nie powinieneś zabraknąć pamięci z powodu ogromnej pamięci podręcznej. IMO, kod powinien zawierać kilka dodatkowych haczyków, takich jak uruchamianie zdarzeń lub wywoływanie metod chronionych przed działaniem „nic nie rób”, które użytkownicy tacy jak ty mogą zastąpić. (Ponadto nie powinny to być wszystkie metody statyczne, aby mogły to zrobić ) Możesz skontaktować się z autorami i złożyć wniosek.Według tych testów , StringTokenizer jest szybszy do dzielenia ciągów, ale nie zwraca tablicy, co czyni go mniej wygodnym.
Jeśli chcesz posortować miliony wierszy, polecam użycie RDBMS.
źródło
Jest to metoda, której używam do analizowania dużych (1 GB +) plików rozdzielanych tabulatorami. Ma znacznie mniejszy narzut niż
String.split()
, ale jest ograniczony dochar
ogranicznika. Jeśli ktoś ma szybszą metodę, chciałbym ją zobaczyć. Można to również zrobić naCharSequence
aCharSequence.subSequence
, ale to wymaga wykonaniaCharSequence.indexOf(char)
(patrz metody pakietuString.indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex)
jeśli zainteresowany).źródło