Всем, кто использует strtok посвящается. Решил сравнить скорость работы strtok и strcharsplit.
Функции
stock strtok(const string[], &index, seperator=' ') { new length = strlen(string); while ((index < length) && (string[index] <= seperator)) { index++; } new offset = index; new result[20]; while ((index < length) && (string[index] > seperator) && ((index - offset) < (sizeof(result) - 1))) { result[index - offset] = string[index]; index++; } result[index - offset] = EOS; return result; }
stock strcharsplit(const string[], &index, seperator=' ') { new result[20], i = 0; if (index != 0 && string[index] != '\0') index++; while (string[index] && string[index] != seperator && string[index] != '\r' && string[index] != '\n') { result[i++] = string[index++]; } return result; }
Скрипт
new string[128] = "Pe4eneg Rulit Vsegda Oga"; new str[64]; new idx = 0; // ---------- new tick = GetTickCount(); for (new i=0;i<50000;i++) { str = strtok(string,idx,' '); str = strtok(string,idx,' '); str = strtok(string,idx,' '); str = strtok(string,idx,' '); idx = 0; } printf("strtok: %d",GetTickCount() - tick); // ---------- idx = 0; tick = GetTickCount(); for (new i=0;i<50000;i++) { str = strcharsplit(string,idx,' '); str = strcharsplit(string,idx,' '); str = strcharsplit(string,idx,' '); str = strcharsplit(string,idx,' '); idx = 0; } printf("strcharsplit: %d",GetTickCount() - tick);
Результаты
strtok: 1449 strcharsplit: 1159 strtok: 1497 strcharsplit: 1147 strtok: 1376 strcharsplit: 1233
Вывод
Функция strcharsplit быстрее strtok примерно на 20%.
Обновлено
Была найдена(тут) более быстрая функция парсинга строки. К сожалению, та функция имеет недостатки: не очищается dest, не работает со спец. символами \n, \r и т.д., нельзя изменить разделитель(потому что используется switch/case).
В итоге я решил написать нечто среднее между скоростью функции u_strtok и правильностью работы функции strtok. Функция strsplit быстрее strcharsplit, но медленнее, чем u_strtok. Зато, эта функция работает идентично strtok.
stock strsplit(dest[], const string[], &index, seperator=' ') { if (index != 0 && string[index] != '\0') { index++; } new i = 0; for (;;) { if (i == 0) { for (;;) { if (string[index] == seperator) { index++; } else { switch (string[index]) { case '\0', '\a', '\b', '\f', '\n', '\r', '\t', '\v': index++; default: break; } } } } if (string[index] == seperator) { break; } switch (string[index]) { case '\0', '\a', '\b', '\f', '\n', '\r', '\t', '\v': break; default: dest[i++] = string[index++]; } } dest[i] = '\0'; }