Может ли const-корректность повысить производительность?
Я много раз читал, что применение const-корректности в вашем коде C или C++ является не только хорошей практикой в отношении ремонтопригодности, но также может позволить вашему компилятору выполнять оптимизацию. Однако я тоже прочитал полную противоположность-что это вообще не влияет на производительность.
поэтому, есть ли у вас примеры, где корректность const может помочь вашему компилятору улучшить производительность вашей программы?
4 ответа:
const
корректность не может улучшить производительность, потому чтоconst_cast
иmutable
находятся в языке и позволяют коду соответственно нарушать правила. Это становится еще хуже в C++11, гдеconst
данные могут, например, быть указателем наstd::atomic
, что означает, что компилятор должен учитывать изменения, внесенные другими потоками.тем не менее, для компилятора тривиально смотреть на код, который он генерирует, и определять, действительно ли он записывает в заданную переменную, и применять оптимизации соответственно.
этим все сказано,
const
правильность-это хороший дело в отношении ремонтопригодности. В противном случае клиенты вашего класса могут нарушить внутренние члены этого класса. Например, рассмотрим стандартstd::string::c_str()
-- если бы он не мог вернуть значение const, вы могли бы закрутить с внутренним буфером строки!не используйте
const
по соображениям производительности. Используйте его по причинам ремонтопригодности.
Да, это может.
большинство
const
s предназначены исключительно для программиста и не помогают компилятору оптимизировать, потому что законно отбрасывать их, и поэтому они не говорят компилятору ничего полезного для оптимизации. Впрочем, некоторыеconst
s не могут быть (юридически) отброшены, и они предоставляют компилятору полезную информацию для оптимизации.в качестве примера, доступ к глобальной переменной, определенной с помощью
const
тип может быть встроен в то время как один безconst
тип не может быть встроен, потому что он может измениться во время выполнения.C++:
int foo1 = 1; const int foo2 = 2; int get_foo1() { return foo1; } int get_foo2() { return foo2; }
asm:
foo1: .long 1 foo2: .long 2 get_foo1(): push rbp mov rbp, rsp mov eax, DWORD PTR foo1[rip] ; foo1 must be accessed by address pop rbp ret get_foo2(): push rbp mov rbp, rsp mov eax, 2 ; foo2 has been replaced with an immediate 2 pop rbp ret
в практическом плане, имейте в виду, что в то время как
const
может улучшить производительность, в большинстве случаев это не будет или это будет, но изменения не будут заметны. Основная полезностьconst
это не оптимизация.
Стив Джессоп дает еще один пример в своем комментарии к исходному вопросу, который поднимает что-то достойное упоминания. В области блока компилятор может вывести, будет ли переменная мутирована и оптимизирована соответствующим образом, независимо от
const
, потому что компилятор может увидеть любой переменной. Напротив, в приведенном выше примере невозможно предсказать, еслиfoo1
будет изменен, так как он может быть изменен в других единицах перевода. Я полагаю, что гипотетический разумный ультра-компилятор может проанализировать всю программу и определить, если это действительно для встроенного доступа кfoo1
... но настоящие компиляторы не могут.
по моему опыту, нет
для скалярных переменных компилятор может определить, когда значение изменяется, и выполнить необходимую оптимизацию самостоятельно.
для указателей на массивы корректность const не гарантирует, что значения действительно постоянны при наличии потенциальных проблем с псевдонимами. Поэтому компилятор не может использовать только модификатор const для выполнения оптимизаций
Если вы ищете оптимизацию, вы должны рассмотреть
__restrict__
или специальные функции модификаторы / атрибуты:http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
немного старый, но все еще применяется: http://www.gotw.ca/gotw/081.htm И еще: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/