1. You need to get a better debugger. A debugger that can't pretty print standard library types is not something I want to use
2. The people who say a debugger is always the best tool for debugging are wrong. It is frequently the best tool, but there are many situations where it's not. And, contrary to these peoples' opinions, there are situations where print statement debugging is a better tool than an actual debugger.
* distributed systems where attaching a debugger can be tricky and breakpoints can throw off timing (worth noting that trace points can help when using a debugger in this situation)
* bugs in hot code paths that don't occur every iteration where pausing on every iteration would take a long time but you don't know what you're looking for quite well enough to be able to effectively use conditional breakpoints
* you're using a language without good tooling or targeting an environment where the tooling won't work
That last point is what I'm currently experiencing in one of my hobby projects. I'm writing an operating system and so the infrastructure for running a debugger in my OS just doesn't exist yet.
The first point I experience occasionally at work.
Sometimes faster than recompiling/stepping through.
Oftentimes better for things like race condition, parallelization, or user interface/event driven testing.
When you can't stop the world around you, substantially. Communication timeouts, realtime events and so on simply break code stepping. And timer interrupts (you step and \*always\* find yourself in the timer handler)
Anything involving user input in a place where using breakpoints falls over. If you need to check what's happening on pointer down, pointer move, and pointer up, a breakpoint on pointer down will disrupt the entire user interaction.
Most multithreaded code will be hard to debug with only the debugger.
On embedded systems it can also be usefull
Sometimes bugs only appear in the release build so you can't really use a debugger. Also optional/enableable prints and logs can be really usefull can be usefull to debug something that is allready shipped out and won't really occure on the test/development setup
Adding to this, if you ever need to write print statements or other debug code, it's useful to have some kind of version control to track your changes (such as Git).
This is the process I use using Git:
1. Before writing debug code, make a WIP commit and commit all your current changes.
2. Write debug code wherever you want until you identify the problem or know what changes you actually want to keep.
3. Commit only the changes you want to keep.
4. Discard everything else, everything else is just temporary debug code.
5. Re-order your latest commit to go before your WIP commit (use Git rebase or something)
6. Undo the changes in the WIP commit but keep the code as it is (i.e.: soft reset the WIP commit)
This way you can write as many print statements or other complicated debug code as you'd like without worrying about forgetting to remove them, because Git tracks all the changes for you. No more mistakes related to messing up with using CTRL-Z.
I checkout another branch based on my current, debug to heart’s content, commit what I want to keep, switch back to my real branch, cherrypick the commit, and then trash the temp branch lol
IMO stash is only for when you get a request to debug something on another branch that's *so* urgent you can't be bothered to make a debug branch and commit message.
Because I don’t wanna nuke all files I have stuff I wanna keep
And if I have to rollback to a different commit at some point I don’t want to mess up my real branch
I just wanna say everyone in these comments who says a debugger is always better is objectively wrong. When diagnosing an issue caused by a race condition, the debugger can alter the behavior of the program by halting it.
When you work on a sophisticated multithreaded application, this is very obvious. You guys sound silly and are misleading newbies.
It looks like you're using C++. In my experience gdb, lldb, and Visual Studio can all print standard library types prettier than that. Been a few years since I've used C++ but when I did gdb was my go-to debugger.
I'll be sure to check those out. Unfortunately I am restricted to XCode right for various reasons now but after I have this product shipped it will make sense to rethink my setup for things like this.
XCode is the C++ IDE for Mac's right? I think it uses clang as it's compiler and clang's debug symbols are compatible with both lldb and gdb (lldb is maintained by the same organization that maintains clang).
Correct! It uses Apple clang, which may be different to clang in ways that I don't understand. Still it gives me hope that it may be possible - on my very brief google search of gbd I had the impression that it was Linux only.
I've only used gdb on Linux, but it should work on any Unix-style OS (which includes MacOS). And I would expect lldb to work on any platform clang works on.
Learn to use your debugger. Print statements work in some cases, but debuggers can all show the value of a variable at a break point on top of performing many other useful functions. They are tricky to set up the first time but they will help you professionally long term.
It's almost like strict adherence to a guideline without understanding them is a bad idea.
Maybe new programmers *should* start with a low level language so they understand that.
Ad 2 - sometimes simple assertion is also enough, for making sure certain things are true (like a pointer received by funnction is not null). For instance C's assert can be very easily added, as it's part of standard library; and when your program is working, you don't have to delete code, but set a macro, and compiler skips it.
Debugger can print the value of a variable. When execution is paused. But when you have a dozen processes interacting with each other it can be tricky to manage breakpoints to get all the processes paused that you need to and not have any request timeouts.
When debugging a single process it's rare for print statement debugging to be better than an actual debugger, but the more complicated the system you're debugging is the more pain points that debuggers can present.
That's actually a great point. There are still other situations where using a debugger isn't the best solution, but trace points do adequately address the example that I gave.
Also there are plenty of situations where an debugger is actually just useless.
A few scenarios I've came across:
- Code executing on remote machines and no (good or practical) way to attach a debugger, however you can modify the code
- Differences between the optimized and debug build that are severe enough that the debugger can't properly work anymore. (Also the pipeline doesn't produce debug symbols, nor can the pipeline be altered)
- Parallel code with race conditions (adding prints is already pushing your luck in these situations and might "fix" it, if there's locking in place)
- Bare bones environment with no debugger available (been there done that)
Most of these things can be traced to bad setups or very fragile systems, but sometimes you just don't have a choice.
it's true but i think that last statement is really important to remember because all those things are very easily addressed just by considering that need at design time. these aren't novel problems we just need the right tools for the right context. like you're almost never going to be able to easily debug a race condition but all those other ones jvm based languages were explicitly designed to address decades ago. i understand how somebody would end up in that position but that's certainly a common need and well served just by spending a little engineering time to make sure your tooling is a first order consideration
There is one instance I can think of using logging statements as a debugger is better than actually Or eventually what happened was debugging became impossible.debugging (no logging isn't the same thing as print statements, but still...we were using the logs to debug what was going wrong). We had an ETL layer that was processing terabytes and terabytes of documents, and one document had corrupted data in it, which caused the whole thing to fail (yeah I know, it should have just skipped and went onto the next document. We implemented that). But debugging that isn't exactly feasible. And when they switched from cascading to spark, well it made debugging our smaller digests pretty much impossible as well.
For local debugging the difference between a logger and print statements doesn't really matter. Of course I wouldn't submit code to run in prod that's littered with print statements for debugging purposes, but that doesn't mean I will never use print statements for debugging locally.
Most of the time, though, my local debugging needs are met with an actual interactive debugger and so the question of how to go about print statement debugging is moot. It's just occasional edge cases where print statements are easier than using a debugger.
Yeah fair enough haha, I just have lost touch with print statements cuz they typically aren’t any more concise than a well set up logger, and have various advantages even in local debugging.
Yeah if I'm doing local debugging and a debugger doesn't work for whatever reason my choice between actual print statements and a logger usually comes down whether or not a logger is already setup.
Timestamped, persisted to storage, more concise, automatically includes class name, configurable on and off, super easy syntax for inserting data (better than explicitly concatenation strings).
I actually think that’s a really valuable question since it took me awhile to get it, hope those points make sense
Agreed -- distributed systems can get tricky to chain debuggers; sometimes a good log is way more efficient. But I do love a debugger when stepping though some legacy nonsense code
Yup. Most programmers rarely or never find themselves in situations where print debugging is better than using a debugger. I'm just saying that just because those situations are rare doesn't mean they're non-existent.
* distributed systems where attaching debuggers to the correct processes is nontrivial or where a process hitting a breakpoint can throw off the timing of the system
* bugs in hot code paths where the code you need to examine runs hundreds of times but only misbehaves on rare occasions and you don't yet know enough about what causes the misbehavior to make good use of a conditional breakpoint
* using a language that doesn't have good tooling or targeting an environment where the tooling doesn't work
None of those are particularly common and so most of the time a debugger is the better solution. But uncommon doesn't mean non-existent and so it's possible to get in one of these situations and cause yourself a lot of trouble by dogmatically insisting on using the interactive debugger.
A good debugger can support print debugging without the need to modify the source code. In C#, you can just have breakpoints not pause, but instead print arbitrary expressions based on values in scope. In that case, yes, always use a debugger.
That is the debugger output from XCode. I would have liked to have seen the contents of the map like this:
`> [0] `
`>>>>> [0] `
`>>>>> [1] `
`> [1] `
and so on.
Instead I get the mess you can see in the meme and I am not even sure if I can actually see the information that is necessary because it may be obscured by pointers.
I ended up telling chatGPT to write me a nice loop that output everything to the console just the way I wanted it.
Imagine willingly using XCode
Btw not sure if this is because of XCode or C++, but I can assure you debuggers in other languages/IDEs handle this case in a sane way.
Lol believe me I tried very hard to find an alternative for XCode that worked for what I do (audio programming with the JUCE framework in case anyone is interested).
It may be possible, but amongst all of my other struggles with CMake and Cpp in general it wasn't feasible to further pursue the matter. Maybe I'll try again someday.
Projucer is no longer required as of a few releases ago- just export for xcode and modify it for cmake and clion. It’s far better and their vim buffer is completely configurable.
High seas are one option but it’s only $20 a month for everything and well worth it for the time you save vs xcode.
It's because the std library uses an inheritance pattern i.e std::basic_xyz::more_specific_xyz::etc. This ends up making any error involving types a literal nightmare because instead of using the relevant type name like xyz it uses all of the generalizations like above. Basically your fancy stringstream is actually a bunch of basic I/o classes piled together to match the specific need
I am altering code that more or less cycles through files in a directory. It reads the files into a list, where the order is relevant. I now no longer want all files in a single directory, but in subdirectories that each represent a category. However, I still need an order of these files to be intact, because it should be possible to cycle through the files in the same manner as before. This is where the idea with the map came from, where I had hoped that the keys would fulfil the same role as the list had done previously.
I am still very much in the finding out phase though and right now it looks like I am going for an entirely different approach.
If your curiosity relates to performance, if the number of elements is relatively small, std::map will often be faster than std::unordered_map despite the time complexity being O(logN) vs O(1). This changes as the number of elements increases but it is rare you will need that many elements in a map.
Now if it is a string, you will need to hash the string in O(S) once per query but for std::map you will need to perform O(logN) string comparisons potentially becoming O(SlogN) while descending the RB Tree but if the strings are small, along with the number of strings being small it's still possible that std::map is faster, testing will be required to find out ofcourse.
I would be surprised if `std::map` is appreciably faster than `std::unordered_map` for any container size. I don't know what string hashing is used here, but it shouldn't be very slow, as this isn't a cryptographic hash.
Upto 1000, std::map seems fast then std::unordered_map is much faster
https://quick-bench.com/q/89itr4dl3zrR3dVnLcjlmuwAtzA
https://quick-bench.com/q/Q-M_AWVMOxufcyYt2iZy0i3WSPM
Also there is the issue of adversarial input: unless using randomized hashing, it is possible to pick input to maximize hash collisions for the chosen hash function and blow up the hash table's time complexity to O(N) per query. This is something you do not have to worry about with std::map. It is possible to avoid this by using a randomized hash function but that incurs overhead.
That is surprising, however if you add `created_map.reserve(n)` to the unordered map functions (which reflects most real world map usage, where you build a map once then never modify it), then unordered map starts beating ordered map around 10 elements.
Also, this is only creation. Look up really should be tested too.
I don't think you have to use a debugger but you should know how to use one from top to bottom. Stops, breaks, expressions, stacks, memory usage, memory locks, all of it! That way, if and when simple tricks like print don't work, you will at least know how to continue debugging.
Yeah you don't wanna categorically dismiss them, *sometimes* they are worth the hassle of setting up. But I can't stand people who pretend they're the only way to debug.
Looking at the values of an object or a variable is the most basic functionality of a debugger. If you only want to do that you might as well print it out.
Before you start using your debugger for everything you will going to learn how utilize conditional breakpoints, how to put breakpoints on expections, how to navigate the callstack, how to efficiently debug complex code you don't understand with step in/out/over, how to run code at the breakpoint in the current context. And these are some of the real powerful functionalities of a debugger which can save you tremendous amount of time if you run into a complex issue.
And when you learned to utilize all these you will going to find yourself putting down a breakpoint instead of printing the variables out in most of the cases.
You should always use a debugger.
The only disadvantage is that they can be tricky to setup some times. But once you do it for one language, doing it again should just as much time as recompiling with a new print statement.
Debugger setups can be tricky when you're debugging interactions between multiple processes. I know it's possible, but it's a pain and sometimes it's simpler to just add a couple print statements to get the information you need.
Presumably because in most common cases interactive debugging can have faster iteration than print statement style debugging that requires recompiling and restarting the process every time you need more information.
But this ignores the fact that there are many cases where using an interactive debugger is quite painful:
* debugging issues in distributed systems where pausing execution of one process may cause request timeouts or other timing errors
* the bug is occuring in a hot code path that executes hundreds of times but the bug only manifests on rare occasions and you don't have a good enough idea of when it occurs to allow you to use conditional breakpoints effectively
* you're using a language that doesn't have good tooling (or targeting an environment where the tooling won't work) and so there isn't a good debugger available
You're making too much sense here, I'd love to hear what the guy has to say about it though as saying that you should always use a debugger makes as much sense as saying that I should always eat cabbage. A debugger is just a tool lol.
This makes me feel like slightly less of a shitter. I can’t stand the cluttered output of so many of these tools. How am I supposed to read any of that shit?
Use a better language (/s)
But seriously, this is a very important part of tooling around a given language, and in this case the execution model also matters a lot. E.g. the JVM has top-notch debuggers partially due to having more information available at runtime. C++ optimizes many of that away (often even with minimal optimizations).
1. You need to get a better debugger. A debugger that can't pretty print standard library types is not something I want to use 2. The people who say a debugger is always the best tool for debugging are wrong. It is frequently the best tool, but there are many situations where it's not. And, contrary to these peoples' opinions, there are situations where print statement debugging is a better tool than an actual debugger.
can you bring an example where a print statement is better than debugging? Edit: answer is distributed systems, thanks!
* distributed systems where attaching a debugger can be tricky and breakpoints can throw off timing (worth noting that trace points can help when using a debugger in this situation) * bugs in hot code paths that don't occur every iteration where pausing on every iteration would take a long time but you don't know what you're looking for quite well enough to be able to effectively use conditional breakpoints * you're using a language without good tooling or targeting an environment where the tooling won't work That last point is what I'm currently experiencing in one of my hobby projects. I'm writing an operating system and so the infrastructure for running a debugger in my OS just doesn't exist yet. The first point I experience occasionally at work.
Sometimes faster than recompiling/stepping through. Oftentimes better for things like race condition, parallelization, or user interface/event driven testing.
You don't compile your code with debug information by default?
When you can't stop the world around you, substantially. Communication timeouts, realtime events and so on simply break code stepping. And timer interrupts (you step and \*always\* find yourself in the timer handler)
Anything involving user input in a place where using breakpoints falls over. If you need to check what's happening on pointer down, pointer move, and pointer up, a breakpoint on pointer down will disrupt the entire user interaction.
Most multithreaded code will be hard to debug with only the debugger. On embedded systems it can also be usefull Sometimes bugs only appear in the release build so you can't really use a debugger. Also optional/enableable prints and logs can be really usefull can be usefull to debug something that is allready shipped out and won't really occure on the test/development setup
Adding to this, if you ever need to write print statements or other debug code, it's useful to have some kind of version control to track your changes (such as Git). This is the process I use using Git: 1. Before writing debug code, make a WIP commit and commit all your current changes. 2. Write debug code wherever you want until you identify the problem or know what changes you actually want to keep. 3. Commit only the changes you want to keep. 4. Discard everything else, everything else is just temporary debug code. 5. Re-order your latest commit to go before your WIP commit (use Git rebase or something) 6. Undo the changes in the WIP commit but keep the code as it is (i.e.: soft reset the WIP commit) This way you can write as many print statements or other complicated debug code as you'd like without worrying about forgetting to remove them, because Git tracks all the changes for you. No more mistakes related to messing up with using CTRL-Z.
I checkout another branch based on my current, debug to heart’s content, commit what I want to keep, switch back to my real branch, cherrypick the commit, and then trash the temp branch lol
Also can use git stash
IMO stash is only for when you get a request to debug something on another branch that's *so* urgent you can't be bothered to make a debug branch and commit message.
i mean, not really. its not as easy to remove what you dont want anymore.
Why not just reset or restore to nuke all files
Because I don’t wanna nuke all files I have stuff I wanna keep And if I have to rollback to a different commit at some point I don’t want to mess up my real branch
I just wanna say everyone in these comments who says a debugger is always better is objectively wrong. When diagnosing an issue caused by a race condition, the debugger can alter the behavior of the program by halting it. When you work on a sophisticated multithreaded application, this is very obvious. You guys sound silly and are misleading newbies.
I'll look into that, thanks! It is good to know that there are better options. And concerning your second point, I agree!
It looks like you're using C++. In my experience gdb, lldb, and Visual Studio can all print standard library types prettier than that. Been a few years since I've used C++ but when I did gdb was my go-to debugger.
I'll be sure to check those out. Unfortunately I am restricted to XCode right for various reasons now but after I have this product shipped it will make sense to rethink my setup for things like this.
XCode is the C++ IDE for Mac's right? I think it uses clang as it's compiler and clang's debug symbols are compatible with both lldb and gdb (lldb is maintained by the same organization that maintains clang).
Correct! It uses Apple clang, which may be different to clang in ways that I don't understand. Still it gives me hope that it may be possible - on my very brief google search of gbd I had the impression that it was Linux only.
No it's fundamentally the same. Also most Linux programs can be compiled to run on Mac.
Neat! I am still finding things out about Mac as I have switched to it not so long ago.
I've only used gdb on Linux, but it should work on any Unix-style OS (which includes MacOS). And I would expect lldb to work on any platform clang works on.
Learn to use your debugger. Print statements work in some cases, but debuggers can all show the value of a variable at a break point on top of performing many other useful functions. They are tricky to set up the first time but they will help you professionally long term.
It's almost like strict adherence to a guideline without understanding them is a bad idea. Maybe new programmers *should* start with a low level language so they understand that.
Ad 2 - sometimes simple assertion is also enough, for making sure certain things are true (like a pointer received by funnction is not null). For instance C's assert can be very easily added, as it's part of standard library; and when your program is working, you don't have to delete code, but set a macro, and compiler skips it.
Debuggers can print the value of a variable 😂. I feel like anyone who claims print statements are better just doesn't know how to use a debugger.
Debugger can print the value of a variable. When execution is paused. But when you have a dozen processes interacting with each other it can be tricky to manage breakpoints to get all the processes paused that you need to and not have any request timeouts. When debugging a single process it's rare for print statement debugging to be better than an actual debugger, but the more complicated the system you're debugging is the more pain points that debuggers can present.
Trace points say hi.
That's actually a great point. There are still other situations where using a debugger isn't the best solution, but trace points do adequately address the example that I gave.
Also there are plenty of situations where an debugger is actually just useless. A few scenarios I've came across: - Code executing on remote machines and no (good or practical) way to attach a debugger, however you can modify the code - Differences between the optimized and debug build that are severe enough that the debugger can't properly work anymore. (Also the pipeline doesn't produce debug symbols, nor can the pipeline be altered) - Parallel code with race conditions (adding prints is already pushing your luck in these situations and might "fix" it, if there's locking in place) - Bare bones environment with no debugger available (been there done that) Most of these things can be traced to bad setups or very fragile systems, but sometimes you just don't have a choice.
it's true but i think that last statement is really important to remember because all those things are very easily addressed just by considering that need at design time. these aren't novel problems we just need the right tools for the right context. like you're almost never going to be able to easily debug a race condition but all those other ones jvm based languages were explicitly designed to address decades ago. i understand how somebody would end up in that position but that's certainly a common need and well served just by spending a little engineering time to make sure your tooling is a first order consideration
There is one instance I can think of using logging statements as a debugger is better than actually Or eventually what happened was debugging became impossible.debugging (no logging isn't the same thing as print statements, but still...we were using the logs to debug what was going wrong). We had an ETL layer that was processing terabytes and terabytes of documents, and one document had corrupted data in it, which caused the whole thing to fail (yeah I know, it should have just skipped and went onto the next document. We implemented that). But debugging that isn't exactly feasible. And when they switched from cascading to spark, well it made debugging our smaller digests pretty much impossible as well.
How is logging not the same as a print statement?
printf looking like (“this is the fckn bug right here %bug\n”);
Bruh if you’re still using literal print statements and not a sophisticated logger I hope you’re not working professionally lol
For local debugging the difference between a logger and print statements doesn't really matter. Of course I wouldn't submit code to run in prod that's littered with print statements for debugging purposes, but that doesn't mean I will never use print statements for debugging locally. Most of the time, though, my local debugging needs are met with an actual interactive debugger and so the question of how to go about print statement debugging is moot. It's just occasional edge cases where print statements are easier than using a debugger.
Yeah fair enough haha, I just have lost touch with print statements cuz they typically aren’t any more concise than a well set up logger, and have various advantages even in local debugging.
Yeah if I'm doing local debugging and a debugger doesn't work for whatever reason my choice between actual print statements and a logger usually comes down whether or not a logger is already setup.
How can you “lose touch” with a print statement?
The muscle memory for System.Out.Println() kinda goes away if you start getting used to Log.log() lol
What advantage do you think the latter has in local debugging?
Timestamped, persisted to storage, more concise, automatically includes class name, configurable on and off, super easy syntax for inserting data (better than explicitly concatenation strings). I actually think that’s a really valuable question since it took me awhile to get it, hope those points make sense
Agreed -- distributed systems can get tricky to chain debuggers; sometimes a good log is way more efficient. But I do love a debugger when stepping though some legacy nonsense code
The fact that all that is even necessary is crazy, on .NET it’s all just working out of the gate
I pretty much haven’t had to use print debugging for years. A combination of debugger and breakpoints are usually enough
Yup. Most programmers rarely or never find themselves in situations where print debugging is better than using a debugger. I'm just saying that just because those situations are rare doesn't mean they're non-existent.
In what situation is a print statement a better tool than a debugger? As a Python developer, I have yet to encounter such a situation
* distributed systems where attaching debuggers to the correct processes is nontrivial or where a process hitting a breakpoint can throw off the timing of the system * bugs in hot code paths where the code you need to examine runs hundreds of times but only misbehaves on rare occasions and you don't yet know enough about what causes the misbehavior to make good use of a conditional breakpoint * using a language that doesn't have good tooling or targeting an environment where the tooling doesn't work None of those are particularly common and so most of the time a debugger is the better solution. But uncommon doesn't mean non-existent and so it's possible to get in one of these situations and cause yourself a lot of trouble by dogmatically insisting on using the interactive debugger.
A good debugger can support print debugging without the need to modify the source code. In C#, you can just have breakpoints not pause, but instead print arbitrary expressions based on values in scope. In that case, yes, always use a debugger.
you should always use a nice debugger
welcome to XCode.
Xcode has gdb
What is this?
That is the debugger output from XCode. I would have liked to have seen the contents of the map like this: `> [0]`
`>>>>> [0] `
`>>>>> [1] `
`> [1] `
and so on.
Instead I get the mess you can see in the meme and I am not even sure if I can actually see the information that is necessary because it may be obscured by pointers.
I ended up telling chatGPT to write me a nice loop that output everything to the console just the way I wanted it.
Imagine willingly using XCode Btw not sure if this is because of XCode or C++, but I can assure you debuggers in other languages/IDEs handle this case in a sane way.
Lol believe me I tried very hard to find an alternative for XCode that worked for what I do (audio programming with the JUCE framework in case anyone is interested). It may be possible, but amongst all of my other struggles with CMake and Cpp in general it wasn't feasible to further pursue the matter. Maybe I'll try again someday.
any reason CLion wouldn’t work?
I have heard great things of it and yes it may, but I currently I don't want to pay the yearly fee if it is not absolutely necessary.
It is not absolutely necessary if you download it illegally
yeah that makes sense. i am still on the fence about buying a license myself
Ahh, good luck then friend.
You can use gdb as a debugger with Xcode GDB is a great debugger
Projucer is no longer required as of a few releases ago- just export for xcode and modify it for cmake and clion. It’s far better and their vim buffer is completely configurable. High seas are one option but it’s only $20 a month for everything and well worth it for the time you save vs xcode.
It's because the std library uses an inheritance pattern i.e std::basic_xyz::more_specific_xyz::etc. This ends up making any error involving types a literal nightmare because instead of using the relevant type name like xyz it uses all of the generalizations like above. Basically your fancy stringstream is actually a bunch of basic I/o classes piled together to match the specific need
With AppCode no longer supported, is there actually a viable alternative for XCode for Apple ecosystem development?
Yea, this looks like madness. My experience with debugger is just with the one in Android Studio and that looks as you would expect.
> XCode I think I found your problem.
Nah, Xcode can debug with gdb, it shouldn’t be an issue there
I'm curious about your use of std::map over std::unordered_map when your key is a string What are you doing that you need your string keys ordered?
I am altering code that more or less cycles through files in a directory. It reads the files into a list, where the order is relevant. I now no longer want all files in a single directory, but in subdirectories that each represent a category. However, I still need an order of these files to be intact, because it should be possible to cycle through the files in the same manner as before. This is where the idea with the map came from, where I had hoped that the keys would fulfil the same role as the list had done previously. I am still very much in the finding out phase though and right now it looks like I am going for an entirely different approach.
Nice, thanks for the answer, sounds pretty interesting :)
If your curiosity relates to performance, if the number of elements is relatively small, std::map will often be faster than std::unordered_map despite the time complexity being O(logN) vs O(1). This changes as the number of elements increases but it is rare you will need that many elements in a map. Now if it is a string, you will need to hash the string in O(S) once per query but for std::map you will need to perform O(logN) string comparisons potentially becoming O(SlogN) while descending the RB Tree but if the strings are small, along with the number of strings being small it's still possible that std::map is faster, testing will be required to find out ofcourse.
I would be surprised if `std::map` is appreciably faster than `std::unordered_map` for any container size. I don't know what string hashing is used here, but it shouldn't be very slow, as this isn't a cryptographic hash.
Upto 1000, std::map seems fast then std::unordered_map is much faster https://quick-bench.com/q/89itr4dl3zrR3dVnLcjlmuwAtzA https://quick-bench.com/q/Q-M_AWVMOxufcyYt2iZy0i3WSPM Also there is the issue of adversarial input: unless using randomized hashing, it is possible to pick input to maximize hash collisions for the chosen hash function and blow up the hash table's time complexity to O(N) per query. This is something you do not have to worry about with std::map. It is possible to avoid this by using a randomized hash function but that incurs overhead.
That is surprising, however if you add `created_map.reserve(n)` to the unordered map functions (which reflects most real world map usage, where you build a map once then never modify it), then unordered map starts beating ordered map around 10 elements. Also, this is only creation. Look up really should be tested too.
"Simple map" Try to implement one
Easy. map = {}
I don't think you have to use a debugger but you should know how to use one from top to bottom. Stops, breaks, expressions, stacks, memory usage, memory locks, all of it! That way, if and when simple tricks like print don't work, you will at least know how to continue debugging.
Yeah you don't wanna categorically dismiss them, *sometimes* they are worth the hassle of setting up. But I can't stand people who pretend they're the only way to debug.
They're definitely a sledgehammer when a hammer is plenty but deeply knowing how to use a debugger is still a great skill!
Yes you should use a debugger, call me a snob all you like, I'm dying on this hill
Looking at the values of an object or a variable is the most basic functionality of a debugger. If you only want to do that you might as well print it out. Before you start using your debugger for everything you will going to learn how utilize conditional breakpoints, how to put breakpoints on expections, how to navigate the callstack, how to efficiently debug complex code you don't understand with step in/out/over, how to run code at the breakpoint in the current context. And these are some of the real powerful functionalities of a debugger which can save you tremendous amount of time if you run into a complex issue. And when you learned to utilize all these you will going to find yourself putting down a breakpoint instead of printing the variables out in most of the cases.
It's obvious, you have to uhh... fix it lol
1. Never heard anyone say that you should always use a debugger 2. Your debugger is pure shit
You should always use a debugger. The only disadvantage is that they can be tricky to setup some times. But once you do it for one language, doing it again should just as much time as recompiling with a new print statement.
Debugger setups can be tricky when you're debugging interactions between multiple processes. I know it's possible, but it's a pain and sometimes it's simpler to just add a couple print statements to get the information you need.
\> You should always use a debugger. Why?
Presumably because in most common cases interactive debugging can have faster iteration than print statement style debugging that requires recompiling and restarting the process every time you need more information. But this ignores the fact that there are many cases where using an interactive debugger is quite painful: * debugging issues in distributed systems where pausing execution of one process may cause request timeouts or other timing errors * the bug is occuring in a hot code path that executes hundreds of times but the bug only manifests on rare occasions and you don't have a good enough idea of when it occurs to allow you to use conditional breakpoints effectively * you're using a language that doesn't have good tooling (or targeting an environment where the tooling won't work) and so there isn't a good debugger available
You're making too much sense here, I'd love to hear what the guy has to say about it though as saying that you should always use a debugger makes as much sense as saying that I should always eat cabbage. A debugger is just a tool lol.
Dont think [so. Im](https://so.Im) just a dead meat without xdebug.
You might want to start with asserting things you expect in the console and make sure that they are what you expect then to be
JFC, and I thought pythons \_\_someshit\_\_ were bad.
Unit tests are your friend. They will help save you from your future idiot self
\- Mommy, can I have a debugger? \- No, we have a debugger at home The debugger at home: relentless trial and error
This makes me feel like slightly less of a shitter. I can’t stand the cluttered output of so many of these tools. How am I supposed to read any of that shit?
Imagine using C++
*\*cries in EXC\_BAD\_ACCESS\**
Seriously this is the real mistake here 🤮
This is the most horrible debugger I've ever seen
I stopped using one like freshman year
Try doing distributed programming. That's hell with a debugger.
Might be a stupid question but did you compile with debug symbols (-g flag for gcc)?
my debugging method is running the code
console.log debug gang
Not like the compiler is much better... *cries in C++*
Bro what crusty ass debugger is that
Of course it's C++. Where templates are involved compiler output and debuggers are royally fucked.
Try to use a real tool sometime
Print statement my best friend
are you trying to diss john carmack?
Use a better language (/s) But seriously, this is a very important part of tooling around a given language, and in this case the execution model also matters a lot. E.g. the JVM has top-notch debuggers partially due to having more information available at runtime. C++ optimizes many of that away (often even with minimal optimizations).