sscanf()
должен интерпретировать строку формата в соответствии с token
и преобразовать содержимое строки. Вы можете избежать ненужного синтаксического анализа строки формата, используя функцию прямого преобразования, такую как atoi()
:
#include <string.h>
#include <stdlib.h>
void Parser_GetQuadToken( const char* token, int16_t* res1, int16_t* res2, int16_t* res3, int16_t* res4 )
{
char* resstr = strchr( token, '=' ) + 1 ;
*res1 = (int16_t)atoi( resstr ) ;
resstr = strchr( resstr, ',' ) + 1 ;
*res2 = (int16_t)atoi( resstr ) ;
resstr = strchr( resstr, ',' ) + 1 ;
*res3 = (int16_t)atoi( resstr ) ;
resstr = strchr( resstr, ',' ) + 1 ;
*res4 = (int16_t)atoi( resstr ) ;
}
Поскольку целью является повышение производительности, необходимо измерить улучшение. Я измерил его в 9 раз быстрее в 64-битной отладочной сборке в VC ++ и в 12 раз быстрее для 32-битного кода. YMMV для вашей цели и компилятора. Оптимизация оказывает незначительное влияние, поскольку она связана с библиотечным кодом.
Обратите внимание, что в приведенной выше реализации столько же проверок на ошибки, сколько и в исходном коде, т. Е. Нет. Вы должны быть уверены, что ввод token
будет действительным как предварительное условие. В моем тесте добавление проверки ошибок оказало незначительное влияние на производительность:
bool Parser_GetQuadToken( const char* token, int16_t* res1, int16_t* res2, int16_t* res3, int16_t* res4 )
{
char* resstr = 0 ;
if( (resstr = strchr( token, '=' )) != NULL )
{
*res1 = (int16_t)atoi( ++resstr ) ;
if( (resstr = strchr( resstr, ',' )) != NULL )
{
*res2 = (int16_t)atoi( ++resstr ) ;
if( (resstr = strchr( resstr, ',' )) != NULL )
{
*res3 = (int16_t)atoi( ++resstr ) ;
if( (resstr = strchr( resstr, ',' )) != NULL )
{
*res4 = (int16_t)atoi( ++resstr ) ;
}
}
}
}
return resstr != NULL ;
}
Однако это может не оказать ожидаемого эффекта - файловый ввод / вывод будет намного медленнее, чем манипулирование памятью и строками, налагаемое sscanf()
- проблема с sscanf()
во встроенных системах чаще связана с требуемым использованием пространства кода и стека.
@ SteveSummit предложил использовать strtol()
. Так как это отслеживает "последнюю позицию" отсканированного, чтобы избежать повторения строки. Вы можете использовать это, чтобы пропустить явный поиск разделителей запятых:
void Parser_GetQuadToken( const char* token, int16_t* res1, int16_t* res2, int16_t* res3, int16_t* res4 )
{
char* resstr = strchr( token, '=' ) ;
*res1 = (int16_t)strtol( ++resstr, &resstr, 10 ) ;
*res2 = (int16_t)strtol( ++resstr, &resstr, 10 ) ;
*res3 = (int16_t)strtol( ++resstr, &resstr, 10 ) ;
*res4 = (int16_t)strtol( ++resstr, &resstr, 10 ) ;
}
В моих тестах это примерно в 12 раз быстрее при отладке и 17 при оптимизации - однако это несколько переменное тестирование в Windows. Я оставлю проверку ошибок на ваше усмотрение.