I ran into these problems with std::unordered_map. While developing my game, I would always run it in debug mode because I need to debug it. Loading a game world was taking around 12 seconds, and it was beginning to grate on me because of the increased iteration times. So I decided to profile it and see what was taking so long. I compiled in release mode to begin debugging, and it magically took the world load time d…
It'd maybe be nice to be able to mark which code gets optimized. If I could make all std as "don't debug this and keep it optimized" I would. I know some debuggers have the option to at least not step into certain code that that doesn't solve the optimization issue
The Sad State of Debug Performance in C++
81–90 of 111 posts
Re: The Sad State of Debug Performance in C++
#82Earlier quoted context omitted.
> Presumably my code has been less than optimally efficient or something Yep, it was either less efficient than it could be, or more clunky, or incorrect. I remember back when boost was still a thing, everyone using boost::shared_ptr indiscriminately. Refcounting has a very nontrivial cost to it if implemented correctly. Things like rvalue refs and std::move allow to properly implement the concept of "ownership trans…
I've been using boost::shared_ptr for 22+ years. My code has no concept of ownership transfer, ever. The reason for shared_ptr in our codebase is not to move ownership around, but to ensure correct lifetimes. For examples, objects in the model cannot die until the view has dropped references to them.
Refcounted pointers don't make that guarantee. They just guarantee that if they are incorrect they will not deallocate (== will leave garbage) and thus never result in a use-after-deletion.
Most of the time they are fine but they can't handle circular structures. This is why C++ has the weak_ptr.
Re: The Sad State of Debug Performance in C++
#83Earlier quoted context omitted.
I've been using boost::shared_ptr for 22+ years. My code has no concept of ownership transfer, ever. The reason for shared_ptr in our codebase is not to move ownership around, but to ensure correct lifetimes. For examples, objects in the model cannot die until the view has dropped references to them.
Yup, that's bad. Unless you actually have a complicated ownership scheme or shared state across multiple threads, unique ownership is preferable on all accounts. At the point where 1) your object graph is complex enough to warrant the ubiquitous use of shared pointers; 2) you can afford the performance hit it's better to use an actual garbage collector, even if it's bolted-on unreal engine-style. With shared_ptr-styl…
Re: The Sad State of Debug Performance in C++
#84Earlier quoted context omitted.
I've been using boost::shared_ptr for 22+ years. My code has no concept of ownership transfer, ever. The reason for shared_ptr in our codebase is not to move ownership around, but to ensure correct lifetimes. For examples, objects in the model cannot die until the view has dropped references to them.
> to ensure correct lifetimes Refcounted pointers don't make that guarantee. They just guarantee that if they are incorrect they will not deallocate (== will leave garbage) and thus never result in a use-after-deletion. Most of the time they are fine but they can't handle circular structures. This is why C++ has the weak_ptr.
The alternative is "no language-level references, any time you want object "Foo", go look it up in some table". We opted not to do that.
Re: The Sad State of Debug Performance in C++
#85Earlier quoted context omitted.
Yup, that's bad. Unless you actually have a complicated ownership scheme or shared state across multiple threads, unique ownership is preferable on all accounts. At the point where 1) your object graph is complex enough to warrant the ubiquitous use of shared pointers; 2) you can afford the performance hit it's better to use an actual garbage collector, even if it's bolted-on unreal engine-style. With shared_ptr-styl…
Our object graph is for a DAW, one of the most complex applications floating around. Multiple threads, some with RT constraints, multiple UIs acting as both view and controller. No GC acceptable here.
Re: The Sad State of Debug Performance in C++
#86Earlier quoted context omitted.
Yup, that's bad. Unless you actually have a complicated ownership scheme or shared state across multiple threads, unique ownership is preferable on all accounts. At the point where 1) your object graph is complex enough to warrant the ubiquitous use of shared pointers; 2) you can afford the performance hit it's better to use an actual garbage collector, even if it's bolted-on unreal engine-style. With shared_ptr-styl…
>It's actually less predictable than a GC that you can run manually at fixed intervals or whenever a convenient opportunity arises. Not really. It's difficult to reason about, but it's entirely deterministic, unlike a tracing GC.
Re: The Sad State of Debug Performance in C++
#87I've been using C++ since 1993. I still don't understand how I've written all this code and never once found myself using, or wishing I could use std::move. Presumably my code has been less than optimally efficient or something, because it seems that most people talking about "modern" C++ view it as absolutely central to the language.
> I've been using C++ since 1993. I still don't understand how I've written all this code and never once found myself using, or wishing I could use std::move. No offense, but are you using modern C++? One of the most common uses of std::move is around ownership transfer of std::unique_ptr - most moderately big projects will have those. Other uses are around preventing copies, etc but those need more thought since you…
We do not use unique_ptr and to be honest I can find little to no use for it anywhere in our 600k lines of C++.
Re: The Sad State of Debug Performance in C++
#88Earlier quoted context omitted.
Our object graph is for a DAW, one of the most complex applications floating around. Multiple threads, some with RT constraints, multiple UIs acting as both view and controller. No GC acceptable here.
as long as you can control when GC runs, it can be acceptable for applications with soft-realtime constraints (not all GC languages give you that level of flexibility though). at least I would prefer that situation over being faced with cascading destruction of refcounted objective-c objects at the most inconvenient moment, with no other recourse than complete rearchitecting.
Re: The Sad State of Debug Performance in C++
#89I'm with Kernigham and Pike: the debugger is for getting a stack trace out of core dumps. Printf is for debugging.
oh where is that quote? that's great!
Re: The Sad State of Debug Performance in C++
#90I've been using C++ since 1993. I still don't understand how I've written all this code and never once found myself using, or wishing I could use std::move. Presumably my code has been less than optimally efficient or something, because it seems that most people talking about "modern" C++ view it as absolutely central to the language.
IMO, a large set of "Modern C++" fanboys have a serious case of "Featuritis"; Merely a focus on the trivial use without understanding the motivation behind it and its place in the larger scheme of building systems. It is like they believe more knowledge of keywords/buzzwords == more expertise.
Even Scott Meyers said this: https://news.ycombinator.com/item?id=27945383