+ 1 к Gui13 за предоставление ссылки на источник gcc stdlib strcmp (http://sourceware.org/git/?p=glibc.git;a=blob;f=string/strcmp.c;h=bd53c05c6e21130b091bd75c3fc93872dd71fe4b;hb=HEAD)!
Вы правы, что strcmp никогда не может быть быстрее, чем прямое сравнение [1], но вопрос в том, будет ли компилятороптимизировать это? Я был напуган, чтобы попытаться измерить это, но я был приятно удивлен тем, насколько легко это было. Мой пример кода (без заголовков):
bool isEmpty(char * str) {
return 0==std::strcmp(str,"");
}
bool isEmpty2(char * str) {
return str[0]==0;
}
И я попытался скомпилировать это, сначала с gcc -S -o- emptystrcmptest.cc
и затем с gcc -S -O2 -o- emptystrcmptest.cc
. К моему приятному удивлению, хотя я не очень хорошо читаю сборку, неоптимизированная версия явно показала разницу, а оптимизированная версия ясно показала, что две функции создали одинаковую сборку.
Итак, я бы сказал, что в целом нет смысла беспокоиться об этом уровне оптимизации.
Если вы используете компилятор для встроенной системы и знаете, что он не справляется с такой простой оптимизацией (или вообще не иметь стандартной библиотеки), используйте специальную версию с ручным кодированием.
Если вы кодируете нормально, выВот более читаемая версия (imho, которая может быть strcmp или strlen или [0] == 0 в зависимости от контекста).
Если вы пишете высокоэффективный код, вы ожидаете, что его будут вызывать тысячи или миллионы раз в секунду, (a) тест, который на самом деле более эффективен, и (b) если читаемая версия на самом деле слишком медленная, попробуйте написать что-нибудь, что скомпилируется для лучшей сборки.
С gcc -S -o- emptystrcmptest.cc
:
.file "emptystrcmptest.cc"
.section .rdata,"dr"
LC0:
.ascii "\0"
.text
.align 2
.globl __Z7isEmptyPc
.def __Z7isEmptyPc; .scl 2; .type 32; .endef
__Z7isEmptyPc:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $LC0, 4(%esp)
movl 8(%ebp), %eax
movl %eax, (%esp)
call _strcmp
movl %eax, -4(%ebp)
cmpl $0, -4(%ebp)
sete %al
movzbl %al, %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
leave
ret
.align 2
.globl __Z8isEmpty2Pc
.def __Z8isEmpty2Pc; .scl 2; .type 32; .endef
__Z8isEmpty2Pc:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
cmpb $0, (%eax)
sete %al
movzbl %al, %eax
popl %ebp
ret
emptystrcmptest.cc:10:2: warning: no newline at end of file
.def _strcmp; .scl 2; .type 32; .endef
С gcc -S -O2 -o- emptystrcmptest.cc
:
.file "emptystrcmptest.cc"
emptystrcmptest.cc:10:2: warning: no newline at end of file
.text
.align 2
.p2align 4,,15
.globl __Z7isEmptyPc
.def __Z7isEmptyPc; .scl 2; .type 32; .endef
__Z7isEmptyPc:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
cmpb $0, (%eax)
sete %al
movzbl %al, %eax
ret
.align 2
.p2align 4,,15
.globl __Z8isEmpty2Pc
.def __Z8isEmpty2Pc; .scl 2; .type 32; .endef
__Z8isEmpty2Pc:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
cmpb $0, (%eax)
sete %al
movzbl %al, %eax
ret
[1] Хотя будьте осторожны - в случаях, более сложных, чем прямой тест на ноль, код библиотеки и компилятора обычно будет лучше, чем ручнойкод.