Прошу прощения за некрозу этого поста. Будучи новичком в DXL, я провел некоторое время с тем же испытанием. Я заметил, что имеющиеся в наличии реализации имеют разные спецификации для "разбиения" строки. Любя язык Ruby , я пропустил реализацию, которая хотя бы близка к версии Ruby String # split .
Может быть, мои выводы будут кому-нибудь полезны.
Вот функциональное сравнение
- Вариант A: Реализация niol (которая на первый взгляд кажется той же самой реализацией, которая обычно встречается в Capri Soft ,
- Вариант B: Реализация PJT,
- Вариант C: Реализация Бретта и
- Вариант D: моя реализация (которая обеспечивает правильную функциональность imo).
Чтобы устранить структурные различия, все реализации были реализованы в функциях, возвращая список Skip
или Array
.
Результаты расщепления
Обратите внимание, что все реализации возвращают разные результаты, в зависимости от их определения "расщепления":
строка mellow yellow
; разделитель ello
splitVariantA returns 1 elements: ["mellow yellow" ]
splitVariantB returns 2 elements: ["m" "llow yellow" ]
splitVariantC returns 3 elements: ["w" "w y" "" ]
splitVariantD returns 3 elements: ["m" "w y" "w" ]
строка now's the time
; разделитель
splitVariantA returns 3 elements: ["now's" "the" "time" ]
splitVariantB returns 2 elements: ["" "now's the time" ]
splitVariantC returns 5 elements: ["time" "the" "" "now's" "" ]
splitVariantD returns 3 elements: ["now's" "the" "time" ]
строка 1,2,,3,4,,
; разделитель ,
splitVariantA returns 4 elements: ["1" "2" "3" "4" ]
splitVariantB returns 2 elements: ["1" "2,,3,4,," ]
splitVariantC returns 7 elements: ["" "" "4" "3" "" "2" "" ]
splitVariantD returns 7 elements: ["1" "2" "" "3" "4" "" "" ]
Сроки
Разделение строки 1,2,,3,4,,
с шаблоном ,
для 10000 раз на моей машине дает следующие значения времени:
splitVariantA() : 406 ms
splitVariantB() : 46 ms
splitVariantC() : 749 ms
splitVariantD() : 1077 ms
К сожалению, моя реализация D самая медленная. Удивительно, но реализация C регулярных выражений довольно быстрая.
Исходный код
// niol, modified
Array splitVariantA(string splitter, string str){
Array tokens = create(1, 1);
Buffer buf = create;
int str_index;
buf = "";
for(str_index = 0; str_index < length(str); str_index++){
if( str[str_index:str_index] == splitter ){
array_push_str(tokens, stringOf(buf));
buf = "";
}
else
buf += str[str_index:str_index];
}
array_push_str(tokens, stringOf(buf));
delete buf;
return tokens;
}
// PJT, modified
Skip splitVariantB(string s, string delimiter) {
int offset
int len
Skip skp = create
if ( findPlainText(s, delimiter, offset, len, false)) {
put(skp, 0, s[0 : offset -1])
put(skp, 1, s[offset +1 :])
}
return skp
}
// Brett, modified
Skip splitVariantC (string s, string delim) {
Skip skp = create
int i = 0
Regexp split = regexp "^(.*)" delim "(.*)$"
while (split s) {
string temp_s = s[match 1]
put(skp, i++, s[match 2])
s = temp_s
}
put(skp, i++, s[match 2])
return skp
}
Skip splitVariantD(string str, string pattern) {
if (null(pattern) || 0 == length(pattern))
pattern = " ";
if (pattern == " ")
str = stringStrip(stringSqueeze(str, ' '));
Skip result = create;
int i = 0; // index for searching in str
int j = 0; // index counter for result array
bool found = true;
while (found) {
// find pattern
int pos = 0;
int len = 0;
found = findPlainText(str[i:], pattern, pos, len, true);
if (found) {
// insert into result
put(result, j++, str[i:i+pos-1]);
i += pos + len;
}
}
// append the rest after last found pattern
put(result, j, str[i:]);
return result;
}