Does const call by reference improve performance when applied to primitive types?

别说谁变了你拦得住时间么 提交于 2019-12-05 05:54:29
Félix Cantournet

My suspicion is that it is advantageous to use call-by-reference as soon as the primitive type's size in bytes exceeds the size of the address value. Even if the difference is small, I'd like to take the advantage because I call some of these functions quite often.

Performance tweaking based on hunches works about 0% of the time in C++ (that's is a gut feeling I have about statistics, it works usually...)

It is correct that the const T& will be smaller than the T if sizeof(T) > sizeof(ptr), so usually 32-bits, or 64, depending on the system..

Now ask yourself :

1) How many built-in types are bigger than 64 bits ?

2) Is not copying 32-bits worth making the code less clear ? If your function becomes significantly faster because you didn't copy a 32bit value to it, maybe it doesn't do much ?

3) Are you really that clever ? (spoiler alert : no.) See this great answer for the reason why it is almost always a bad idea : https://stackoverflow.com/a/4705871/1098041

Ultimately just pass by value. If after (thorough) profiling you identify that some function is a bottleneck, and all of the other optimizations that you tried weren't enough (and you should try most of them before this), pass-by-const-reference.

Then See that it doesn't change anything. roll-over and cry.

Emile Vrijdags

I addition to the other answers I would like to note that when you pass a reference and use (aka dereference) that a lot in your function, it could be slower than making a copy.

This is because local variables to a function (usually) get loaded into the cache together, but when one of them is a pointer/reference and the function uses that, it could result in a cache miss. Meaning it needs to go to the (slower) main memory to get the pointed to variable, which could be slower than making the copy which is loaded in cache together with the function.

So even for 'small objects' it could be potentially faster to just pass by value.

(I read this in the very good book: Computer Systems: a programmers perspective)

Some more interesting discussion on the whole cache hit/miss topic: How does one write code that best utilizes the CPU cache to improve performance?

const is a keyword which is evaluated at compiletime. It does not have any impact on runtime performance. You can read some more about this here: https://isocpp.org/wiki/faq/const-correctness

On a 64-bit architecture, there is no primitive type---at least not in C++11---which is larger than a pointer/reference. You should test this, but intuitively, there should be the same amount of data shuffled around for a const T& as for an int64_t, and less for any primitive where sizeof(T) < sizeof(int64_t). Therefore, insofar as you can measure any difference, passing primitives by value should be faster if your compiler is doing the obvious thing---which is why I stress that if you need certainty here, you should write a test case.

Another consideration is that primitive function parameters can end up in CPU registers, which makes accessing them as fast as a memory access can be. You might find there are more instructions being generated for your const T& parameters than for your T parameters when T is a primitive. You could test this by checking the assembler output by your compiler.

I was taught:

  • Pass by value when an argument variable is one of the fundamental built-in types, such as bool, int, or float. Objects of these types are so small that passing by reference doesn't result in any gain in efficiency. Also if you want to make a copy of a variable.

  • Pass a constant reference when you want to efficiently pass a value that you don't need to change.

  • Pass a reference only when you want to alter the value of the argument variable. But to try to avoid changing argument variables whenever possible.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!