В C быстрее использовать стандартную библиотеку или написать свою собственную функцию? - PullRequest
8 голосов
/ 13 июля 2010

Например, в <ctype.h> есть такие функции, как isalpha().

Я хочу знать, быстрее ли написание собственной функции isalpha, чем вызов isalpha?


Спасибо за все ваши мгновенные ответы!просто хочу прояснить мой вопрос:

так даже для функции isalpha?потому что вы можете просто передать символ и проверить, находится ли символ между 'a' и 'z' ||'A' и 'Z'?

другой вопрос: когда вы включаете библиотеку std, например ctype.h, и просто вызываете одну функцию, например isalpha, будет ли загружен файл (я имею в виду все строки кода)?Меня беспокоит то, что большой размер замедлит работу программы

Ответы [ 10 ]

65 голосов
/ 13 июля 2010

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

Стандартные библиотечные функции сильно оптимизированы и очень хорошо протестированы.Кроме того, стандартная библиотека, поставляемая с вашим компилятором, может использовать встроенные функции компилятора и другие низкоуровневые детали, которые вы не можете использовать в своем собственном коде.

14 голосов
/ 13 июля 2010

isalpha не просто проверяет, находится ли его аргумент в диапазонах A-Z, a-z.Цитирование стандарта C (§7.4.1.2):

Функция isalpha проверяет любой символ, для которого isupper или islower имеет значение true, или любой символ, который является одним из набора, специфичного для локалибуквенных символов , для которых ни один из iscntrl, isdigit, ispunct или isspace не является истинным.

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


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

int isalpha(int c) {
    return ((unsigned int)(c | 32) - 97) < 26U;
}
8 голосов
/ 13 июля 2010

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

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

Написав свой собственный isalpha, вы можете убедиться, что он и только он включен в ваш окончательный двоичный файл.

В некоторых ограниченных случаях вы можете получить более высокие скорости, когда выесть очень конкретная вещь, которую вы хотите сделать, и библиотека обрабатывает более общий случай.Опять же, необходимо, только если конкретный цикл является узким местом в системе.Вы также можете выбрать другой компромисс между скоростью и пространством, чем тот, который был выбран автором библиотеки, например, изменяется:

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

на:

int isalpha (int c) {
    static int map[256] = {0,0,0,0,...,1,1,1,...,0,0,0};
    return map[c & 0xff];
}

(потенциально) быстреереализация за счет дополнительного хранилища для карты (и вам необходимо понимать среду выполнения, поскольку она не переносима).

Еще одна причина не использовать их - предоставить более безопасный способ работы с такими вещами, как строкигде безопасность / надежность является КРИТИЧЕСКИМ фактором.Как правило, это будет стоить вам гораздо больше времени, чтобы доказать правильность.

6 голосов
/ 13 июля 2010

Здесь уже есть куча ответов, но нет ни одного, кроме адреса Стивена Кэнона, самой важной части: различной семантики.Это наиболее важный фактор при выборе используемых функций.

Стандартные функции библиотеки C isalpha и т. Д. Предназначены для работы в соответствии с текущей локалью.Если вы оставите языковой стандарт по умолчанию "C" (не вызывая setlocale), они будут иметь очень предсказуемое поведение, но это исключает использование единого стандартизированного метода для приложения для обнаружения и использования предпочтительной кодировки символов системы / пользователя., форматирование чисел, язык сообщений и другие предпочтения локализации.

С другой стороны, если вы реализуете свой собственный isalpha (оптимальная реализация - ((unsigned)c|32)-'a'<26 или если вам нравится код, более самодокументируемый, ((unsigned)c|('A'^'a')-'a'<='z'-'a'), он всегда будет очень предсказуемым, независимо от того,

Я бы зашел так далеко, чтобы прикрепить , считающийся вредным , к использованию стандартных isalpha и т. д. функций для всего, кроме наивной обработки текста, предполагаемой вформат локали пользователя.Эти функции особенно не подходят для анализа файлов конфигурации, текстовых сетевых транзакций, HTML, источников языка программирования и т. Д. (Единственное исключение - isdigit, для которого ISO C должен быть эквивалентен return (unsigned)c-'0'<10;.) На другом концеВ целом, если вы пишете приложение с расширенной обработкой текста на естественном языке (например, текстовым процессором или веб-браузером), потребуется гораздо более сложная обработка свойств символов, чем может обеспечить библиотека C, и вы должны искать хорошийБиблиотека Unicode.

6 голосов
/ 13 июля 2010

Стандартные библиотечные функции написаны, предположительно, очень умными людьми и тщательно проверены, отлажены и оптимизированы.Они были проверены, возможно, миллионы раз в каждой мыслимой производственной среде.Скорее всего, ваши пользовательские функции не будут лучше или быстрее.

2 голосов
/ 13 июля 2010

Хотя это, скорее всего, не будет медленнее, если вы будете осторожно писать это, я почти гарантирую, что вы не собираетесь делать что-то более оптимизированное, чем то, что уже есть. Единственный случай, о котором я могу подумать, - это если это функция, и вы делаете это несколько раз в строке - но если это макрос, вы не сможете ее превзойти. Используйте стандарт.

1 голос
/ 13 июля 2010

Интересно, что реализация isalpha () в вашем вопросе медленнее, чем самая распространенная реализация, предоставляемая библиотеками C 30 лет назад.Помните, что эта функция будет использоваться в критическом внутреннем цикле вашего обычного компилятора Си.:)

Я признаю, что текущие реализации библиотек, вероятно, немного медленнее, чем раньше, из-за проблем с набором символов, с которыми нам приходится сталкиваться сегодня.

1 голос
/ 13 июля 2010

Единственный раз, когда я не использую что-то в стандартной библиотеке, это когда чего-то не хватает, если не включено определенное расширение этой библиотеки.

Например, чтобы получить asprintf() в GNU C,вам нужно включить _GNU_SOURCE до включения <stdio.h>.Было даже время, когда strdup() был поражен или пропущен в <string.h>.

Если я сильно зависим от этих расширений, то я стараюсь включить их в свою базу кода, чтобы мне не пришлосьнапишите kludges, чтобы обойти их отсутствие.

Тогда бывают редкие случаи, когда вы хотите откатить свою собственную версию чего-либо, что, например, дает поведение POSIX (или что-то еще) по умолчанию для лучшего способа.

Кроме этого, реализация чего-то из stdc самостоятельно выглядит несколько глупо, за исключением ценности хорошего учебного упражнения.

1 голос
/ 13 июля 2010

во многих средах C / C ++ (например, VisualC) доступен источник «C Runtime Library» (CRT). Посмотрите на код в функции CRT, а затем попытайтесь подумать: «Можете ли вы сделать это лучше?».

0 голосов
/ 13 июля 2010

Несколько строк или одна строка кода на C не обязательно переводят в самое простое и быстрое решение.Память о while (- len) * d ++ = * s ++;определенно самый медленныйБиблиотеки, как правило, сделаны хорошо и быстро, и вам может быть трудно их улучшить.Места, где вы можете увидеть выигрыш, находятся на конкретных платформах, где вы знаете кое-что о платформе, чего нет у компилятора.Например, целью может быть 32-битный процессор, но вы, возможно, знаете, что 64-битные выравниваемые обращения выполняются быстрее и, возможно, захотите изменить библиотеку, чтобы воспользоваться этой особой ситуацией.Но в целом для всех платформ для всех целей вы, скорее всего, не добьетесь большего успеха, специальные оптимизации для конкретных целей были написаны для популярных целей и находятся в библиотеке C для популярных компиляторов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...