On Fri, Feb 12, 2016 at 1:25 AM, Michael Marcin
On 2/12/2016 1:39 AM, Emil Dotchevski wrote:
On Thu, Feb 11, 2016 at 9:02 PM, Michael Marcin
wrote: But I don't want to pay for them in retail builds.
Good, I don't, either.
Sorry, I don't follow at all then.
If .get() isn't specified as UB when a value is not ready how are you going to avoid the overhead?
Specifically .get() must do *at least* an if statement before returning the value.
Calling shared_ptr::get() is always well defined. It contains no ifs.
And I'm arguing that whether you throw or not should rarely be a question
of performance. If hitting the intersection limit in a raytracing program leads to an invalid frame, you should report that error by throwing an exception. This has zero performance cost if functions are being inlined, which they are at the lowest levels of a raytracer. Generally, if you can afford the "if" statement to detect the error, you can afford to throw.
Sorry I don't follow. Are you suggesting that the raytracer should be inlined into every call site?
I avoid using inline except if the profiler tells me it's needed. If it is needed, then I inline regardless of whether the function emits exceptions or not.
What I think you're saying is that where I want to write code that looks like:
result<int> bar() { return std::make_error_code( std::errc::bad_address ); }
int main() { int foo;
auto _foo = bar(); if ( _foo ) { foo = _foo.get(); } else { foo = 0; }
return foo; }
I should instead write code that looks like:
int bar() { throw std::system_error( std::make_error_code( std::errc::bad_address ) ); }
int main() { int foo;
try { foo = bar(); } catch ( std::system_error& e ) { foo = 0; }
return foo; }
And I should expect equal performance?
Obviously not, because you're always throwing. Throw may incur overhead, certainly does on Windows. What I'm saying is that when you don't actually throw, exception handling overhead occurs exactly where function call overhead occurs, and can be eliminated completely by inlining. In ~20 years in the video game industry I have never needed to implement my
own STL, and modern STL implementations are a lot better than in the old days. On the other hand years ago I did have to refactor a company's home-grown STL replacement to fold templates to reduce bloat, since otherwise the executable was over 20 megs on a platform with 32 megs of RAM. Ironically, the STL on that platform was folding the templates automatically. Too bad they had it banned.
Your experience differs from my own.
EASTL just (officially) released to much fanfare. https://github.com/electronicarts/EASTL
It's very easy to find performance problems in even current shipping standard libraries. 2 examples: See what happens when you insert a duplicate key into a std::map VS2015. Or look towards the 17x perf increase in iostreams float serialization coming in VS2015 update 2.
Yes I'm familiar with EASTL. I generally don't care how slow STL is, except when something shows up on my radar (profiler), in which case usually the reason is user error. Regardless, consider that if a particular use of std::map is too slow, you don't need a faster std::map, you need a faster implementation only for the operations needed in this particular use of std::map. Such implementation can be a lot faster than STL or EASTL because it isn't generic. Emil