Как вычислить длину строки в C эффективно (вовремя)?
Прямо сейчас я делаю:
int calculate_length(char *string) {
int length = 0;
while (string[length] != '\0') {
length++;
}
return length;
}
Но это очень медленно по сравнению с strlen (), например, есть ли какой-либо другой способ сделать это?
Спасибо.
Править: Я работаю в среде отдельных программ, мне не разрешают использовать внешний lib включая "string.h".
Самым простым способом является вызов strlen ()
. Серьезно. Он уже оптимизирован поставщиками компиляторов и/или библиотек, чтобы быть максимально быстрым для вашей архитектуры.
Одной из распространенных оптимизаций является удаление необходимости увеличения счетчика и вычисления длины из указателя:
size_t my_strlen(const char *s)
{
const char *anchor = s;
while(*s)
s++;
return s - anchor;
}
-121--2109221- Диапазон является именно таким: что-то определяется его началом и концом, а не его содержимым. «Итерация» в диапазоне не имеет смысла в общем случае. Рассмотрим, например, «итерацию» по диапазону, создаваемому двумя датами. Не могли бы вы повторить по дням? по месяцам? по годам? по неделям? Это не совсем ясно. ИМО, тот факт, что это разрешено для прямых диапазонов, следует рассматривать только как удобный метод.
Если вы хотите повторить назад в таком диапазоне, вы всегда можете использовать downto
:
$ r = 10..6
=> 10..6
$ (r.first).downto(r.last).each { |i| puts i }
10
9
8
7
6
Вот еще несколько мыслей от других о том, почему трудно и разрешить итерацию, и последовательно иметь дело с обратными диапазонами.
-121--752756-Из исходного кода FreeBSD :
size_t
strlen(const char *str)
{
const char *s;
for (s = str; *s; ++s);
return(s - str);
}
По сравнению с вашим кодом, это, вероятно, очень хорошо сопоставляется с командой ассемблера, что может объяснить большую разницу в производительности.
C rings Внутренне неэффективность , существуют две причины использования Конвенции ASCIZ:
Из них академик в этом случае, поскольку вы не используете стандартную библиотеку, вторая легко преодолена путем создания функций или макросов, которые предоставляют преобразования из строк C до более эффективной конвенции, такие как строки Паскаля. Дело в том, что вам не нужно быть рабым к Конвенции C, если вы не используете библиотеку C.
Реализуйте и используйте интерфейс INotifyPropertyChanged . Прохладным способом сделать это без последовательности литералов является здесь .
-121--1579638- На процессорах i386 libc часто используется ультраоптимизированная версия strlen
, часто написанная на языке сборки. В статье « Длина последовательности » объясняется, как они работают.
Вот одна оптимизированная версия для OpenBSD . (Они также имеют портативную версию .) Вот версия для GNU libc .
Самый простой способ состоит в том, чтобы позвонить Strlen ()
. Серьезно. Это уже оптимизировано вашим поставщиком компилятора и / или библиотеки, чтобы быть как можно быстрее для вашей архитектуры.
Одна общая оптимизация состоит в том, чтобы удалить необходимость увеличения счетчика, и вычислять длину от указателя:
size_t my_strlen(const char *s)
{
const char *anchor = s;
while(*s)
s++;
return s - anchor;
}
strlen ()
. Шансы того, что если бы кто-то нашел лучший, более быстрый общий метод, Стрлен был бы заменен этим.
SQL для Smarties Джо Селко. Мне нравится, путь он охватывает методы представления наборов данных, которые, по вашему мнению, не сразу впишутся в реляционную модель.
(источник: amazon.com )
Посмотрите на библиотеку GNU C strlen ()
источник .
Он использует ряд неочевидных трюков, чтобы набрать скорость, не опускаясь на сборку, в том числе:
и т.д.
Взгляните на исходный код strlen в стандартной libc. Функции в стандартных библиотеках, как правило, сильно оптимизированы. Посмотрите здесь (закодировано в сборке) - это из GNU libc.
size_t
DEFUN(strlen, (str), CONST char *str)
{
int cnt;
asm("cld\n" /* Search forward. */
/* Some old versions of gas need `repne' instead of `repnz'. */
"repnz\n" /* Look for a zero byte. */
"scasb" /* %0, %1, %3 */ :
"=c" (cnt) : "D" (str), "0" (-1), "a" (0));
return -2 - cnt;
}
Еще один способ ускорить счетчик Char - использовать векторизацию!
Вот пример того, как это сделать по отношению к строкам, закодированным UTF8:
Даже быстрее подсчет символов UTF-8,
http://www.daemonology.net/blog/2008-06-05 -Faster-utf8-strlen.html
strlen()
. Скорее всего, если бы кто-нибудь нашел лучший, более быстрый универсальный метод, то strlen был бы заменен на него.