Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Парсинг строк чисел


Автор: o2n3e 11.11.2011, 06:29
Есть строки вида "X123.123Y123.123I123.123J123.123" - это набор координат. Строк в файле от десятков тысяч, до десятков миллионов. 
Задача: Производительность. На парсинг пары миллионов строк есть милисекунд 200, т.е. раза в два быстрее.

Изначально было реализованно на atof(), но это медленно. Числа имеют вид .###, т.е. всегда 3 знака после запятой - atof() был выпилен, и заменён atoi(из "123.123"  просто убералась точка) - медленно.

Моих знаний хватило на http://liveworkspace.org/code/80ab95dc767fb0017afa6740fb68d9cf - медленно, примерно в 10раз бысрее atof() и 6раз atoi().
Числа всегда правильные и в одном порядке, грязный хак "*p > ',' && *p < 'A'" допустим, так же как и stoi() без проверки, числа от -60000.000 до 60000.000 - char g[12] хватит.

 Прошу указать ляпы, влияющие на производительность и направить на путь истинный, если что-то не так.

На моей машине - это 1100мс. Код должен работать на атоме 1.6ггц, который раза в 3медленней моего процессора.
Процессор:
 model name      : Intel® Core™2 CPU          6320  @ 1.86GHz
 cpu MHz         : 3149.476
Компилятор: gcc версия 4.6.2 (Gentoo 4.6.2 p1.0, pie-0.4.5) -O3 
P.S. Опыт программирования месяца 3, реально часов 30-40, прошу сильно не пинать.

Автор: boostcoder 11.11.2011, 06:59
o2n3e, приаттач файл. и побольше.

Добавлено через 14 секунд
в смысле, файл со строками.

Автор: borisbn 11.11.2011, 08:10
лови
http://liveworkspace.org/code/f9ae7688fc627276b6d18bd3b88ee6c2

Автор: math64 11.11.2011, 09:18
stoi лучше переписать так (чтобы не было лишних разыменоваий указателя):
Код

int stoi( const char ** pp )
{
    const char* p = *pp
    int num = 0;
    int sign = 1;
    char ch;
    unsigned int digit;
    ch = *p;
    if ( ch == '-' )
    {
        sign = -1;
        ch = *++p;
    }
    while ( (digit = ch - '0') <= 9 )
    {
        num = num * 10 + digit;
        ch = *++p;
        if (ch == '.' )
            ch  = *++p;
    }
    *pp = p;
    return sign * num;
}


Добавлено через 5 минут и 18 секунд
Компилировать лучше в C без плюсов, использовать можно и в C++

Автор: volatile 11.11.2011, 10:43
Цитата(o2n3e @  11.11.2011,  06:29 Найти цитируемый пост)
Есть строки вида "X123.123Y123.123I123.123J123.123" - это набор координат. Строк в файле от десятков тысяч, до десятков миллионов. 
Задача: Производительность. На парсинг пары миллионов строк есть милисекунд 200

Длина строки = 32 символа. 
Пара миллионов строк ~ 66,000,000 байт. 

Милисекунд 200, то есть за секунду нужно обработать 330 мб.

Имхо, упрется в производительность диска.
330 Мб/сек - это слишком дофига, если это не RAID сервер какой-нибудь.
Цитата(o2n3e @  11.11.2011,  06:29 Найти цитируемый пост)
Код должен работать на атоме 1.6ггц


Хотя может я уже отстал от жизни, и такие диски номальны?

Автор: bsa 11.11.2011, 11:24
Цитата(volatile @  11.11.2011,  11:43 Найти цитируемый пост)
Хотя может я уже отстал от жизни, и такие диски номальны?
Вроде похожую скорость выдает самый навороченный SSD.

Автор: o2n3e 11.11.2011, 12:41
Цитата(volatile @ 11.11.2011,  10:43)
Цитата(o2n3e @  11.11.2011,  06:29 Найти цитируемый пост)
Есть строки вида "X123.123Y123.123I123.123J123.123" - это набор координат. Строк в файле от десятков тысяч, до десятков миллионов. 
Задача: Производительность. На парсинг пары миллионов строк есть милисекунд 200

Длина строки = 32 символа. 
Пара миллионов строк ~ 66,000,000 байт. 

Милисекунд 200, то есть за секунду нужно обработать 330 мб.

Имхо, упрется в производительность диска.
330 Мб/сек - это слишком дофига, если это не RAID сервер какой-нибудь.
Цитата(o2n3e @  11.11.2011,  06:29 Найти цитируемый пост)
Код должен работать на атоме 1.6ггц


Хотя может я уже отстал от жизни, и такие диски номальны?

200мс - это на парсинг, без учёта io.

time ./symbols 123.pp (программка, которую я скопипастил где-то в интернетах.)
File contains 28331954 symbols.

real    0m0.439s
user    0m0.431s
sys     0m0.007s

time cat 123.pp &> /dev/null 

real    0m0.008s
user    0m0.001s
sys     0m0.008s

Файл с миллионом строк, 28331954 символов. И да, там ссд стоит 200МБ на чтение.

Автор: volatile 11.11.2011, 15:15
Цитата(o2n3e @  11.11.2011,  12:41 Найти цитируемый пост)
real    0m0.008s
user    0m0.001s
sys     0m0.008s

так я не понял, вы решили свою проблему, или нет?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)