- About Flibble - 9 Updates
- Compute Unique Numbers in a Set - 7 Updates
- Overuse of 'auto' - 1 Update
- Is it possible to support structual bind like [a, b, ...] = x; - 1 Update
David Brown <david.brown@hesbynett.no>: Jan 16 11:32AM +0100 On 13/01/2023 22:43, Chris M. Thomasson wrote: > debugger would show that the vector contained no elements, however, one > was there. Then there are other oddities. > I have never had this problem with MSVC before. Are you debugging optimised code here? Remember that when single-stepping or using breakpoints, a debugger is working primarily with the generated object code. And when looking at variables, it is mainly using the data in memory or registers. But there is often a disconnect between the lines of the source code and the generated object code - a line you step over might /logically/ put an element into a vector, but the actual change to the data structure could be done far latter in the code. MSVC has traditionally had quite a simplistic handling for a lot of code generation - it has done little in the way of re-arranging code. But I have heard (I don't use the tool myself) that is does more manipulation these days. When using gcc and a debugger, it is quite normal for single-stepping to jump around the code, for things to happen long before or long after you might think from the "current" source line, for variables to be "optimised out", etc. Debugging optimised code is something of an art. |
David Brown <david.brown@hesbynett.no>: Jan 16 11:37AM +0100 On 14/01/2023 23:44, Chris M. Thomasson wrote: >> Perhaps that >> was the issue you had? > In debug mode. "Debug mode" is mostly a meaningless concept. Many IDE's set up two different build configurations - one they call "Debug" with low optimisation and lots of debugger information, and one they call "Release" with high optimisation and little debugger information. But there is not really such a thing as "optimised" code and "unoptimised" code - compilers can enable or disable different passes and different kinds of optimisations. Some "optimisations" are done even when compilers are set to "no optimisation", and some optimisation passes that are possible are not done even on "highest optimisation" flags. (And some "optimisations" can make code slower in practice.) At best, "debug mode" reduces the risk of seeing such disconnects between the source code and the effect of the object code, but it will not eliminate it. |
Muttley@dastardlyhq.com: Jan 16 11:31AM On Mon, 16 Jan 2023 11:32:34 +0100 >jump around the code, for things to happen long before or long after you >might think from the "current" source line, for variables to be >"optimised out", etc. Debugging optimised code is something of an art. And debugging optimised multithreaded code will end up with you gibbering in a corner shouting "Deadlock!" or "Race!" at any nearby pigeons. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jan 16 11:45AM -0800 On 1/16/2023 2:37 AM, David Brown wrote: > At best, "debug mode" reduces the risk of seeing such disconnects > between the source code and the effect of the object code, but it will > not eliminate it. I have a lot of experience with MSVC. Optimization is disabled in Debug mode by default. I have not artificially altered the optimization settings. I have never had these problems with the MSVC debugger before. Your comment just made me check, and it's disabled in Debug mode. Mr. Flibble is right. The debugger is not up to par. Damn. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jan 16 11:46AM -0800 On 1/16/2023 2:32 AM, David Brown wrote: >> one was there. Then there are other oddities. >> I have never had this problem with MSVC before. > Are you debugging optimised code here? No. You made me double check the settings for debug mode. They are disabled. I have never had this problem before in MSVC. > jump around the code, for things to happen long before or long after you > might think from the "current" source line, for variables to be > "optimised out", etc. Debugging optimised code is something of an art. The MSVC has always worked really damn good, up until the recent version... Damn! |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jan 16 11:51AM -0800 >> "optimised out", etc. Debugging optimised code is something of an art. > And debugging optimised multithreaded code will end up with you gibbering in > a corner shouting "Deadlock!" or "Race!" at any nearby pigeons. MSVC's debugger was always pretty damn good. I have used it to debug nightmare multi-threaded code created by somebody else, where I had to pause threads at a specific line, in order to reproduce a certain bug that would only trip once in a blue moon. Found it during artificially stress and load testing. This was a long time ago. Actually, I think I wrote about it here some years ago on this group. Optimization is turned off in Debug mode. Wrt to the IDE: https://i.ibb.co/SV3dMQ7/image.png Never had this problem before. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jan 16 11:52AM -0800 On 1/16/2023 2:37 AM, David Brown wrote: > At best, "debug mode" reduces the risk of seeing such disconnects > between the source code and the effect of the object code, but it will > not eliminate it. https://i.ibb.co/SV3dMQ7/image.png |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jan 16 11:57AM -0800 On 1/16/2023 11:52 AM, Chris M. Thomasson wrote: >> between the source code and the effect of the object code, but it will >> not eliminate it. > https://i.ibb.co/SV3dMQ7/image.png I wonder if frame pointers has something to do with it. The thing is that MSVC always just worked. I have never experienced anything like this in it before. ;^o |
Mr Flibble <flibble@reddwarf.jmc.corp>: Jan 16 08:49PM On Mon, 16 Jan 2023 11:45:16 -0800, Chris M. Thomasson wrote: > settings. I have never had these problems with the MSVC debugger before. > Your comment just made me check, and it's disabled in Debug mode. Mr. > Flibble is right. The debugger is not up to par. Damn. As your codebase doesn't look as involved as mine do you think you are in a position to create a test case and create a MSVC defect report? In the meantime I recommend downgrading to VS2019. /Flibble |
Ralf Goertz <me@myprovider.invalid>: Jan 16 09:46AM +0100 Am Sun, 15 Jan 2023 08:57:24 -0800 (PST) > > … > Where N is the range and M the number of elements to choose, it's O(N) > in space and time. So unsuitable if N is very much larger than M. I just tried it out. Both methods (mine with the corrected off by 1 error) applied 100000 times outputting the last result: ./rg 10 1 1000 193 198 257 384 474 581 606 620 682 954 0.718732s ./rg 990 1 1000 … 0.715686s ./bonita 10 1 1000 919 888 875 567 563 499 323 306 61 34 14.0962s ./bonita 990 1 1000 … 4.7713s The problem seems to be the unordered_set. I created it outside the loop (just like my vector), but I had to empty it at the beginning of the loop. (Is there another way to reuse it?) So in theory you're right but I guess the set approach is a heavy burden. My loop: for (int k=0; k < 100000 ; ++k) { fill( values.begin(), values.begin() + n, 1); fill( values.begin() + n, values.end(), 0); shuffle(values.begin(), values.end(), mt); } bonita's: for (int k=0; k < 100000 ; ++k) { values.erase( values.begin(), values.end()); //her stuff } |
Ralf Goertz <me@myprovider.invalid>: Jan 16 10:21AM +0100 Am Mon, 16 Jan 2023 09:46:15 +0100 > loop (just like my vector), but I had to empty it at the beginning of > the loop. (Is there another way to reuse it?) So in theory you're > right but I guess the set approach is a heavy burden. Surprisingly, Bonita's method also seems to be very dependent on the range: ./rg 10 1 10000 214 2035 2188 3525 4142 5765 6021 6571 7000 8902 7.09215s (No surprise here.) ./bonita 10 1 10000 7400 7185 5343 4357 2990 2011 1478 1078 859 719 184.93s (Wow!) |
Bonita Montero <Bonita.Montero@gmail.com>: Jan 16 01:35PM +0100 Am 16.01.2023 um 10:21 schrieb Ralf Goertz: > ./bonita 10 1 10000 > 7400 7185 5343 4357 2990 2011 1478 1078 859 719 > 184.93s Test the algorithm without screen output ! |
Ralf Goertz <me@myprovider.invalid>: Jan 16 02:42PM +0100 Am Mon, 16 Jan 2023 13:35:57 +0100 > > 7400 7185 5343 4357 2990 2011 1478 1078 859 719 > > 184.93s > Test the algorithm without screen output ! I did of course! The timer starts immediately before the loop and stops after it, before only the last result is output. Your version: #include <iostream> #include <unordered_set> #include <charconv> #include <random> #include <concepts> #include <chrono> #include <cstring> using namespace std; using namespace std::chrono; int main( int argc, char** argv ) { try { if( argc < 4 ) return cout << argv[0] << " n from to" << endl, EXIT_FAILURE; auto parse = []( char const *str, char const *err ) { size_t value; if( from_chars_result fcr = from_chars( str, str + strlen( str ), value ); (bool)fcr.ec || *fcr.ptr ) throw invalid_argument( err ); return value; }; size_t n = parse( argv[1], "wrong number of values" ); if( !n ) return EXIT_SUCCESS; size_t from = parse( argv[2], "wrong from-value" ), to = parse( argv[3], "wrong to-value" ); if( from > to ) swap(from, to); if( n - 1 > to - from ) return cout << "n is too small" << endl, EXIT_FAILURE; unordered_set<size_t> values; mt19937_64 mt; uniform_int_distribution<size_t> uid( from, to ); steady_clock::time_point t1 = steady_clock::now(); for (int k=0; k < 100000 ; ++k) { values.erase( values.begin(), values.end()); if( to - from != (size_t)-1 && to - from + 1 < n / 2 ) { values.reserve( n ); while( values.size() < n ) { size_t value; do value = uid( mt ); while( values.contains( value ) ); values.emplace( value ); } } else { if( to - from == (size_t)-1 ) throw bad_alloc(); values.reserve( to - from + 1 ); size_t i = from - 1; do values.emplace( ++i ); while( i != to ); while( values.size() > n ) for( ; ; ) { auto itRemove = values.find( uid( mt ) ); if( itRemove == values.end() ) continue; values.erase( itRemove ); break; } } } steady_clock::time_point t2 = steady_clock::now(); for( size_t value : values ) cout << value << " "; cout << endl << duration_cast<duration<double>>(t2 - t1)<<endl; } catch( exception const &exc ) { return cout << exc.what() << endl, EXIT_FAILURE; } } and mine: #include <algorithm> #include <iostream> #include <random> #include <charconv> #include <vector> #include <cstring> #include <chrono> using namespace std; using namespace std::chrono; int main( int argc, char** argv ) { try { if( argc < 4 ) return cout << argv[0] << " n from to" << endl, EXIT_FAILURE; auto parse = []( char const *str, char const *err ) { size_t value; if( from_chars_result fcr = from_chars( str, str + strlen( str ), value ); (bool)fcr.ec || *fcr.ptr ) throw invalid_argument( err ); return value; }; size_t n = parse( argv[1], "wrong number of values" ); if( !n ) return EXIT_SUCCESS; size_t from = parse( argv[2], "wrong from-value" ), to = parse( argv[3], "wrong to-value" ); if( from > to ) swap(from, to); if( n - 1 > to - from ) return cout << "n is too small" << endl, EXIT_FAILURE; mt19937_64 mt; vector<int> values( to - from + 1); steady_clock::time_point t1 = steady_clock::now(); for (int k=0; k < 100000 ; ++k) { fill(values.begin(), values.begin() + n, 1); fill(values.begin() + n, values.end(), 0); shuffle(values.begin(), values.end(), mt); } steady_clock::time_point t2 = steady_clock::now(); for( size_t i=0; i < values.size(); ++i ) if( values[i]) cout << i+from << " "; cout << endl << duration_cast<duration<double>>(t2 - t1)<<endl; } catch( exception const &exc ) { return cout << exc.what() << endl, EXIT_FAILURE; } } |
Ralf Goertz <me@myprovider.invalid>: Jan 16 02:46PM +0100 Resent the reply, since I can't see it on my server. Am Mon, 16 Jan 2023 13:35:57 +0100 schrieb Bonita Montero > > 7400 7185 5343 4357 2990 2011 1478 1078 859 719 > > 184.93s > Test the algorithm without screen output ! I did of course! The timer starts immediately before the loop and stops after it, before only the last result is output. Your version: #include <iostream> #include <unordered_set> #include <charconv> #include <random> #include <concepts> #include <chrono> #include <cstring> using namespace std; using namespace std::chrono; int main( int argc, char** argv ) { try { if( argc < 4 ) return cout << argv[0] << " n from to" << endl, EXIT_FAILURE; auto parse = []( char const *str, char const *err ) { size_t value; if( from_chars_result fcr = from_chars( str, str + strlen( str ), value ); (bool)fcr.ec || *fcr.ptr ) throw invalid_argument( err ); return value; }; size_t n = parse( argv[1], "wrong number of values" ); if( !n ) return EXIT_SUCCESS; size_t from = parse( argv[2], "wrong from-value" ), to = parse( argv[3], "wrong to-value" ); if( from > to ) swap(from, to); if( n - 1 > to - from ) return cout << "n is too small" << endl, EXIT_FAILURE; unordered_set<size_t> values; mt19937_64 mt; uniform_int_distribution<size_t> uid( from, to ); steady_clock::time_point t1 = steady_clock::now(); for (int k=0; k < 100000 ; ++k) { values.erase( values.begin(), values.end()); if( to - from != (size_t)-1 && to - from + 1 < n / 2 ) { values.reserve( n ); while( values.size() < n ) { size_t value; do value = uid( mt ); while( values.contains( value ) ); values.emplace( value ); } } else { if( to - from == (size_t)-1 ) throw bad_alloc(); values.reserve( to - from + 1 ); size_t i = from - 1; do values.emplace( ++i ); while( i != to ); while( values.size() > n ) for( ; ; ) { auto itRemove = values.find( uid( mt ) ); if( itRemove == values.end() ) continue; values.erase( itRemove ); break; } } } steady_clock::time_point t2 = steady_clock::now(); for( size_t value : values ) cout << value << " "; cout << endl << duration_cast<duration<double>>(t2 - t1)<<endl; } catch( exception const &exc ) { return cout << exc.what() << endl, EXIT_FAILURE; } } and mine: #include <algorithm> #include <iostream> #include <random> #include <charconv> #include <vector> #include <cstring> #include <chrono> using namespace std; using namespace std::chrono; int main( int argc, char** argv ) { try { if( argc < 4 ) return cout << argv[0] << " n from to" << endl, EXIT_FAILURE; auto parse = []( char const *str, char const *err ) { size_t value; if( from_chars_result fcr = from_chars( str, str + strlen( str ), value ); (bool)fcr.ec || *fcr.ptr ) throw invalid_argument( err ); return value; }; size_t n = parse( argv[1], "wrong number of values" ); if( !n ) return EXIT_SUCCESS; size_t from = parse( argv[2], "wrong from-value" ), to = parse( argv[3], "wrong to-value" ); if( from > to ) swap(from, to); if( n - 1 > to - from ) return cout << "n is too small" << endl, EXIT_FAILURE; mt19937_64 mt; vector<int> values( to - from + 1); steady_clock::time_point t1 = steady_clock::now(); for (int k=0; k < 100000 ; ++k) { fill(values.begin(), values.begin() + n, 1); fill(values.begin() + n, values.end(), 0); shuffle(values.begin(), values.end(), mt); } steady_clock::time_point t2 = steady_clock::now(); for( size_t i=0; i < values.size(); ++i ) if( values[i]) cout << i+from << " "; cout << endl << duration_cast<duration<double>>(t2 - t1)<<endl; } catch( exception const &exc ) { return cout << exc.what() << endl, EXIT_FAILURE; } } |
Muttley@dastardlyhq.com: Jan 16 04:38PM On Mon, 16 Jan 2023 14:42:50 +0100 >> Test the algorithm without screen output ! >I did of course! The timer starts immediately before the loop and stops >after it, before only the last result is output. Your version: But wait, didn't she state that her algorithm was "perfect"? I simply won't believe Bonita has more hubris and self delusion than an angry mouse. |
Bonita Montero <Bonita.Montero@gmail.com>: Jan 16 09:06PM +0100 > But wait, didn't she state that her algorithm was "perfect"? I simply won't > believe Bonita has more hubris and self delusion than an angry mouse. And you don't check that Ralf's code does sth. completely different. |
David Brown <david.brown@hesbynett.no>: Jan 16 11:17AM +0100 On 14/01/2023 08:24, Juha Nieminen wrote: > I write: "Nothing of what I wrote is controversial." > You read: "Nothing of what I wrote is controversial, how could anyone > disagree with me?" Perhaps you don't know what the word "controversial" actually means? Your written English is much better than most native English speakers', but anyone can make a mistake. If something is "controversial", it means people have different opinions about it - there is a fair amount of disagreement. If something is /not/ controversial, or "uncontroversial", it means that there is /no/ disagreement about it of any relevance. (There's always the odd extremist, such as the c.l.c. member who thinks "#define R return" is a good start to a program.) No one is reading between the lines here - anyone who writes that their own opinion, which differs from others, is "uncontroversial" is either ignorant or arrogant, or has not written what they meant to write. You are not ignorant - and you don't like been seen as arrogant. Perhaps this whole branch of the thread is due to your thinking that "uncontroversial" means "widely held opinion" ? > I am not objecting to the disagreements. You clearly have been objecting to them! > I am objecting to the repeated > confrontational attitude shown by some people who seem to be set on > trying to "deconvert" me from this heresy. But you expect others to believe /your/ repeated but unsupported claims, veiled accusations, and unveiled profanities? Don't you see any hypocrisy in this? Here's a little thought experiment. Imagine, for a moment, that other people really have found that using "i" as an index variable can make some code easier to read and clearer to understand, compared to using a more descriptive name with full words. For someone with the personal experience to back that up, how do you think your posts appear? You are telling that person they are insane, and that everyone knows without doubt that they are wrong. You are telling them that their experience as a professional developer for decades, is /wrong/. You write with such a determined, uncompromising conviction in your own ideas that you leave no room for variation, opinion, or personal opinion. And then you accuse /others/ of being confrontational. So imagine yourself on the other side of the table for a moment, re-read your own posts, and consider how they look. > have taken this as their hill to die on. (You may accuse me of that > very same thing, and you would have a point, but I am the one being > on the defensive here.) You have a /very/ distorted view of this thread. /Very/ distorted. There is only /one/ person in this thread who is fanatical about an idea, and that is /you/. You have expressed an extremist view on identifiers. Everyone else here has simply said that while we all agree on the main principles, opinions and experience in the details will vary by person, project, and circumstance. > something I disagree with, some people here only take that one part > and assert that Google fully disagrees with me. And then accuse me > of just taking one part and ignoring the others. Do you /still/ not understand? We all /agree/ with you about the part of Google's guidelines that you quoted. Any serious programmer knows to code for readability, and pick good identifiers that can be understood by other people. Even programmers who never look at other people's code learn that if you write cryptic code with poor identifiers, you won't understand your own code after a few months or years. We all agree on "optimise for readability and understandable code, not for brevity or identifier size". > I am not ignoring the part of Google's coding guideline I disagree > with. I quoted the part that I agree with, to highlight that it's > not some kind of unique controversial stance. No one has /ever/ suggested that this part of Google's guidelines are particularly controversial, or that you are unusual in agreeing with them - we /all/ agree with them more or less. (People might have different opinions on how much project-specific knowledge should be required by people reading code, but that's details, not principle.) The disagreement is on your stance that /all/ identifiers should be full words and fully descriptive. It is that opinion that is unusual and extreme - it is contrary to Google's guidelines and others that I have seen, contrary to common practice and idiomatic code, and several people here (including me) have said that in their experience, short identifiers (such as loop index "i") often /increase/ readability and code understanding in small scopes. But I have no problem in accepting that /your/ experience might be different and /your/ opinion might be different from mine here - I don't say you are wrong just because you disagree with Google and others here. I really don't understand how this can still be unclear to you. > then defend it against criticism, than it is to present criticism > of someone's idea. If someone criticizes the thing I suggested, > it's natural to respond to that criticism in defense of the idea. Feel free to try to defend your opinion. I would like to see your reasoning, or understand what the circumstances are in which you find descriptive identifiers critical even in small and obvious scopes. So far I have seen nothing but repeated assertions, and appeals to code guidelines that disagree with you. But please stick to the controversial issues - /not/ the things we all agree upon. |
"Öö Tiib" <ootiib@hot.ee>: Jan 15 03:40PM -0800 On Sunday, 15 January 2023 at 21:38:02 UTC+2, quanzhou wrote: > auto [a, ..., b] = y; > auto [...,a, b] = z; > helps to get the last member variable of the right side type. I do not understand what it means. Can you describe a problem and then write short example program that solves the problem using that feature? |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment