Pawn. Быстрая замена strtok
1 минут
Всем, кто использует 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';
}