В C это быстрее, чтобы пользоваться стандартной библиотекой или записать Вашу собственную функцию?

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

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


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

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

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

9
задан draw 13 July 2010 в 01:50
поделиться

10 ответов

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

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

65
ответ дан 4 December 2019 в 05:50
поделиться

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

0
ответ дан 4 December 2019 в 05:50
поделиться

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

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

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

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

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

1
ответ дан 4 December 2019 в 05:50
поделиться

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

6
ответ дан 4 December 2019 в 05:50
поделиться

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

2
ответ дан 4 December 2019 в 05:50
поделиться

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

1
ответ дан 4 December 2019 в 05:50
поделиться

Как правило, по возможности всегда следует использовать библиотеки 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];
}

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

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

8
ответ дан 4 December 2019 в 05:50
поделиться

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

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

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

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

6
ответ дан 4 December 2019 в 05:50
поделиться

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

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

1
ответ дан 4 December 2019 в 05:50
поделиться

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

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

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


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

int isalpha(int c) {
    return ((unsigned int)(c | 32) - 97) < 26U;
}
15
ответ дан 4 December 2019 в 05:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: