Оптимизированные реализации некоторых функций из ctype.h - PullRequest
1 голос
/ 18 июля 2011

В одном из моих приложений на C, которые я использую, ниже приведены функции из ctype.h:

isalpha (), isspace (), ispunct (), tolower ().

После профилирования я вижу, что в вызовах этих функций есть некоторые узкие места (в основном мое приложение выполняет обработку символов / строк из входного текстового файла, и, следовательно, эти функции вызываются исчерпывающе внутри критических циклов). Я хочу оптимизировать их по скорости. и иметь собственную реализацию, если это поможет.

Где я могу найти такие или логику для их реализации?

Ответы [ 5 ]

4 голосов
/ 18 июля 2011

Вы можете реализовать их как макросы или встроенные функции:

#define IS_ALPHA(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))
#define IS_SPACE(x) ((x) == ' ' || (x) == '\t')
... etc.

Обратите внимание, однако, что исходные значения isalpha, isspace, ispunct и т. Д. Зависят от текущей локали и могут давать разныерезультаты в зависимости от языка.

2 голосов
/ 18 июля 2011

Вы можете быстро реализовать эти функции, используя справочную таблицу из 256 элементов.Для isalpha () i-й элемент равен 1, если символ, значение ASCII которого равно i, является буквенно-цифровым.Тогда isalpha - это просто поиск по таблице.

Вы можете сэкономить место и закодировать все эти функции одной таблицей, выделив один бит каждой записи в результат одной функции.Затем каждая функция просто ищет запись для переданного символа и маскирует бит, который ей нужен.

Dave

2 голосов
/ 18 июля 2011

Мне кажется странным, что такие функции могут стать вашим узким местом; скорее всего, они могут принять во внимание локаль, и это делает их «медленнее». Если вы можете игнорировать это, то вы можете реализовать их так же легко, как (например: это просто идея, написанная на лету)

bool isalpha(int c)
{
   return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}

bool isspace(int c)
{
   return c == ' ' || c == '\t'; // || whatever other char you consider space
}

bool ispunct(int c)
{
   static const char *punct = ".;!?...";
   return strchr(punct, c) == NULL ? false : true; // you can make this shorter
}

int tolower(int c)
{
   if ( !isalpha(c) ) return c;
   return (c >= 'A' && c <= 'Z') ? c - 'A' : c;
}

Затем сделайте их встроенными функциями.

0 голосов
/ 18 июля 2011

Посмотрите на заголовок ctype.h - ваша библиотека компилятора, вероятно, уже предоставляет способ встроить эти функции или реализовать их как макросы (если по какой-либо причине встроенный не поддерживается).(Кстати - какую компилятор и целевую платформу вы используете?)

Если эти вещи уже встроены в макросы, то вы можете опубликовать некоторые подробности о том, как вы используете функции.Возможно, есть способ быстрого вызова некоторых из этих функций (например, если isspace() имеет значение true, вам не нужно вызывать isalpha() или ispunct(), поскольку они не должны быть истинными).

0 голосов
/ 18 июля 2011

В общем, люди, которые пишут библиотечный код, очень хорошие инженеры-программисты, и эти функции были настроены на n-ую степень. Если вы не можете удалить некоторые из случаев, которые эти функции должны учитывать, у вас будут проблемы с соответствием их производительности.

...