- std::string::assign range - 11 Updates
- Getters & Setters argument - 5 Updates
- The begin of the scope of an identifier - 4 Updates
- The begin of the scope of an identifier - 1 Update
Christopher Pisz <nospam@notanaddress.com>: Mar 05 07:11PM -0600 On 3/5/2015 4:47 PM, Victor Bazarov wrote: > Still, the only way to know for sure why the iterator method is slower > is to profile it. > V So, I got Xperf to work after watching a few hours of videos and working through a lot of out of date information. It reports that Method 1 has 44 heap allocations for a size of 217,357. Method 2 has 26 heap allocations for a size of 194,437. I rely on my high precision timer for the time of execution for both. Method 1 :0.283209 Method 2 :0.0216563 I can't really find anything about istream_iterator or std::inserter though. I like the code in method 1, it feels cleaner. I want to understand if there is another step I am missing or something else I can do similar. It is fairly often I'd want to copy the contents of one stream to a string or to another stream. -- I have chosen to troll filter/ignore all subthreads containing the words: "Rick C. Hodgins", "Flibble", and "Islam" So, I won't be able to see or respond to any such messages --- |
Paavo Helde <myfirstname@osa.pri.ee>: Mar 05 11:55PM -0600 Christopher Pisz <nospam@notanaddress.com> wrote in > Method 2 :0.0216563 > That's quite a difference! What's going on under the hood with the > iterator method? The stream classes are meant for reading and writing *formatted* text at high level (streaming a sequence of C++ objects of arbitrary classes to and from a file). The current locale is taken into account on every step, end-of-line conversions done, etc. The iterator works in this layer even if it actually does no transformations. I would not be surprised if there were a couple of virtual function calls involved with reading each character. OTOH, by using rdbuf() you actually say that you do not want all that formatting and translation and want just to get the file content as it is on the disk. Naturally this is a lot faster. Still, I would expect a difference of at most 3-4 times, the stream abstractions are not that bad. Looks like you are testing non-optimized code. Also, the times like 0.02 seconds are too close to the OS process scheduling granularity, plus the effects from OS file caching may show up. I would put some loops in main() to get larger times, and the very first runs of both methods should be ignored. hth Paavo |
Juha Nieminen <nospam@thanks.invalid>: Mar 06 08:19AM > std::copy(std::istream_iterator<char>(file), > std::istream_iterator<char>(), > std::inserter(textToParse, textToParse.begin())); What's the problem with std::string textToParse(std::istream_iterator<char>(file), std::istream_iterator<char>()); --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 06 01:29PM On 6 Mar 2015 12:17:09 GMT > to merge them into a single statement. > So, the requirement of »one statement« > really is no requirement. Well at least Christopher does not take the approach of answering a question where the intent is obvious but the wording slightly amiss with a pedantically correct but completely useless answer. I think it is generally better to be helpful than to try to be "clever". Chris |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 06 02:28PM On 6 Mar 2015 13:59:11 GMT > »line« or »statement«, it is better to learn it > (when posting into a technical programming newsgroup), > than to accuse others. Then let me meet pedantry with pedantry. Christopher did not "accuse others". So far as there was an accusation (which seems a somewhat paranoid view of the world on your part) it came from me. On other hand, I did not use the words 'line' or 'statement', the failure to understand which you criticize as forfeiting the right to criticize. You knew full well that when Christopher referred to "statement" he meant a non-compound statement, or possibly "expression". I am afraid you have "previous" on this one. Chris |
Victor Bazarov <v.bazarov@comcast.invalid>: Mar 06 10:00AM -0500 On 3/5/2015 8:11 PM, Christopher Pisz wrote: > do similar. > It is fairly often I'd want to copy the contents of one stream to a > string or to another stream. I took your code and changed it a bit so I could time it on Windows. It didn't have the ~14-fold difference like in your example, only about 1.5-fold (the iterator method taking longer by ~50%). Run your test after building it in release (with optimization) and ensure that the text file has been placed in the file cache (by running a couple times and only noting the last run). Or swap the methods (call the 2 before calling 1), just to be sure. The operation is very quick on Windows with shorter files, so profiling here doesn't make much sense. I would venture to point out, though that the iterator method makes more function calls, probably. And, after all, it's QoI of the library, of course. V -- I do not respond to top-posted replies, please don't ask |
Christopher Pisz <nospam@notanaddress.com>: Mar 06 10:54AM -0600 On 3/6/2015 2:19 AM, Juha Nieminen wrote: > std::string textToParse(std::istream_iterator<char>(file), > std::istream_iterator<char>()); > --- news://freenews.netfront.net/ - complaints: news@netfront.net --- Just that I don't know it, but that looks to be better. So, taking your suggestions in combination with Victor's, here is my current listing: // Shared Includes #include "Exception.h" #include "PerformanceTimer.h" // Standard Includes #include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <cstdio> const unsigned int NUM_ITERATIONS = 100; //-------------------------------------------------------------------------------------------------- void Method1() { std::ifstream file("test.txt"); if( !file ) { // Error throw Shared::Exception(__FILE__, __LINE__, "Cannot open test file"); } std::string textToParse(std::istream_iterator<char>(file), std::istream_iterator<char>()); file.close(); } //-------------------------------------------------------------------------------------------------- void Method2() { std::ifstream file("test.txt"); if( !file ) { // Error throw Shared::Exception(__FILE__, __LINE__, "Cannot open test file"); } std::string textToParse; file >> std::noskipws; std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::inserter(textToParse, textToParse.begin())); file.close(); } //-------------------------------------------------------------------------------------------------- void Method3() { std::ifstream file("test.txt"); if( !file ) { // Error throw Shared::Exception(__FILE__, __LINE__, "Cannot open test file"); } std::stringstream textToParse; textToParse << file.rdbuf(); file.close(); } //-------------------------------------------------------------------------------------------------- int main() { Method1(); Method2(); Method3(); Shared::PerformanceTimer timer; for(unsigned count = 0; count < NUM_ITERATIONS; ++count) { Method1(); } std::cout << "Method 1 :" << timer.Stop() << std::endl; timer.Start(); for(unsigned count = 0; count < NUM_ITERATIONS; ++count) { Method2(); } std::cout << "Method 2 :" << timer.Stop() << std::endl; timer.Start(); for(unsigned count = 0; count < NUM_ITERATIONS; ++count) { Method3(); } std::cout << "Method 3 :" << timer.Stop() << std::endl; } and the output is: Method 1 :0.012716 Method 2 :0.361421 Method 3 :0.141371 -- I have chosen to troll filter/ignore all subthreads containing the words: "Rick C. Hodgins", "Flibble", and "Islam" So, I won't be able to see or respond to any such messages --- |
Christopher Pisz <nospam@notanaddress.com>: Mar 06 11:06AM -0600 On 3/6/2015 10:54 AM, Christopher Pisz wrote: > Method 1 :0.012716 > Method 2 :0.361421 > Method 3 :0.141371 I take it back, something is fruity with Juha's suggestion. I see a warning "warning C4930: 'std::string textToParse(std::istream_iterator<_Ty>,std::istream_iterator<_Ty> (__cdecl *)(void))': prototyped function not called (was a variable definition intended?)" and cannot seem to use the string afterward without compiler errors that claim it isn't a compatible type. I don't follow. Using msvc 2012. -- I have chosen to troll filter/ignore all subthreads containing the words: "Rick C. Hodgins", "Flibble", and "Islam" So, I won't be able to see or respond to any such messages --- |
Victor Bazarov <v.bazarov@comcast.invalid>: Mar 06 02:56PM -0500 On 3/6/2015 12:06 PM, Christopher Pisz wrote: > definition intended?)" and cannot seem to use the string afterward > without compiler errors that claim it isn't a compatible type. I don't > follow. Using msvc 2012. Change that line to read std::string textToParse(std::istream_iterator<char>{file}, std::istream_iterator<char>{}); (note the curly braces), and don't use pre-C++11 compiler :-) (actually I'm not sure it's going to work with VC++ 2012, I used 2013 and got this result: Method 1 :498549 Method 2 :305819 Method 3 :110364 (with an 18K file, and those are the processor ticks, using the Windows QueryPerformanceCounter) How big is your file? Another note: make sure the optimizer does not throw away the result of the Method1. It's quite possible that since you're not returning it anywhere, the optimizer might change the code to never create the object in the first place. Think of returning the string from those functions (as in 'std::string Method1(...') Here is my (corrected) code: //-------------------------------------------------------------------------------------------------- // Standard Includes #include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <cstdio> #include <Windows.h> const unsigned int NUM_ITERATIONS = 100; //-------------------------------------------------------------------------------------------------- std::string Method1() { std::ifstream file("test.txt"); if (!file) { // Error throw 1; } std::string textToParse(std::istream_iterator < char > {file}, std::istream_iterator < char > {}); file.close(); return textToParse; } //-------------------------------------------------------------------------------------------------- std::string Method2() { std::ifstream file("test.txt"); if (!file) { // Error throw 22; } std::string textToParse; file >> std::noskipws; std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::inserter(textToParse, textToParse.begin())); file.close(); return textToParse; } //-------------------------------------------------------------------------------------------------- std::string Method3() { std::ifstream file("test.txt"); if (!file) { // Error throw 333; } std::stringstream textToParse; textToParse << file.rdbuf(); file.close(); return textToParse.str(); } //-------------------------------------------------------------------------------------------------- int main() { Method1(); Method2(); Method3(); LARGE_INTEGER t0, t1; QueryPerformanceCounter(&t0); for (unsigned count = 0; count < NUM_ITERATIONS; ++count) { Method1(); } QueryPerformanceCounter(&t1); std::cout << "Method 1 :" << t1.QuadPart - t0.QuadPart << std::endl; QueryPerformanceCounter(&t0); for (unsigned count = 0; count < NUM_ITERATIONS; ++count) { Method2(); } QueryPerformanceCounter(&t1); std::cout << "Method 2 :" << t1.QuadPart - t0.QuadPart << std::endl; QueryPerformanceCounter(&t0); for (unsigned count = 0; count < NUM_ITERATIONS; ++count) { Method3(); } QueryPerformanceCounter(&t1); std::cout << "Method 3 :" << t1.QuadPart - t0.QuadPart << std::endl; } //-------------------------------------------------------------------------------------------------- V -- I do not respond to top-posted replies, please don't ask |
Luca Risolia <luca.risolia@linux-projects.org>: Mar 06 10:32PM +0100 Il 06/03/2015 18:06, Christopher Pisz ha scritto: > definition intended?)" and cannot seem to use the string afterward > without compiler errors that claim it isn't a compatible type. I don't > follow. According to the language rules "std::istream_iterator<char>()" is a declaration of "function taking no arguments returning istream_iterator<char>". To force the compiler to treat the construct as an expression surround it with extra parentheses: std::string textToParse(std::istream_iterator<char>(file),(std::istream_iterator<char>())); |
Victor Bazarov <v.bazarov@comcast.invalid>: Mar 06 05:09PM -0500 On 3/6/2015 4:32 PM, Luca Risolia wrote: > an expression surround it with extra parentheses: > std::string > textToParse(std::istream_iterator<char>(file),(std::istream_iterator<char>())); And to expand on that, the sequence of tokens std::istream_iterator<char>(file) can be also treated as a declaration of an object called 'file' of type 'istream_iterator<char>', the parentheses are superfluous and ignored. Thus the entire original declaration of 'textToParse' is a declaration of a function that takes two arguments and returns a std::string. The name of the first argument ("file") in that case is ignored. V -- I do not respond to top-posted replies, please don't ask |
Robert Wessel <robertwessel2@yahoo.com>: Mar 05 09:33PM -0600 >> 969 years. >Oldest human was Methuselah. They knew how to take >care of themselves and others. Even if you make the (rather big) assumption that the bible has historical accuracy, it does not assert that Methuselah was the oldest human, but he is the oldest it mentions, and perhaps the oldest in the genealogy leading to Noah, although that's still something of a stretch. |
woodbrian77@gmail.com: Mar 05 09:53PM -0800 > human, but he is the oldest it mentions, and perhaps the oldest in the > genealogy leading to Noah, although that's still something of a > stretch. OK, oldest documented human was Methuselah. |
Robert Wessel <robertwessel2@yahoo.com>: Mar 06 02:45AM -0600 >> genealogy leading to Noah, although that's still something of a >> stretch. >OK, oldest documented human was Methuselah. Nah. Just hanging around the middle east... En-men-lu-ana, a king of Sumar, reigned for 43,200 years. Presumably he was alive during that time. There are a bunch of other Sumarian kings who hung around a really long time. Aži Dahaka ruled for a thousand years. Just ask the Zoroastrians. |
David Brown <david.brown@hesbynett.no>: Mar 06 09:49AM +0100 >> genealogy leading to Noah, although that's still something of a >> stretch. > OK, oldest documented human was Methuselah. There were equally well documented Sumerian kings who ruled for tens of thousands of years each. The authors of the books of Moses took a lot of inspiration from Sumerian stories and legends - they probably copied the habit of exaggerating lifespans too. Other old documented humans include some ancient Persian kings, as well as many characters from India and the far east. Remember, "documented" does not mean "true" ! |
Stuart Redmann <DerTopper@web.de>: Mar 06 04:28PM JiiPee wrote: [snip] > private: > float f; > }; Actually, that's a Really Good Idea (TM). That's what Ada95 has in advantage of C++, you can create real number types quite easily. Lot's of bugs would never have occurred had the program been written in Ada, like the infamous bug in libTIFF, where the number of bytes to be copied from a section was computed as int variable. Since the size of the section is stored in the TIFF file including the 4 bytes of the section header, the int variable had to be decreased by 4. If a malicious attacker created a TIFF file, where the section size was stored with a value <4, the int variable became negative, so that it got interpreted as UINT_MAX. LibTIFF would then try to copy that many bytes from the TIFF file, which could lead to stack corruption and privilege escalation. This would never have happened in an Ada95 program, because the data type "Integer" is always the last choice for a variable. Unfortunately, C++ did not offer an equally easy way to define numeric data types (typedef is insufficient there) :-( Another thing is the source of many (avoidable) errors is implicit type conversions. More than one time I shot myself in the foot by passing inadvertently a float into a parameter that should actually be a bool. That passes compilation totally unnotized. Had I tried to pass a Float for a Bool, my folly would have been recognized on the spot. I know that it is easily possible to create a matching type system in C++, but unfortunately the C++ "mindset" has already been poisoned with the wide-spread usage of the native data types like int and float. Just my 2cents. Stuart PS: Please don't mistake me for a C++ hater. I love it heartily. I just wish that it wouldn't spring so many traps. |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 06 12:05AM Sorry, I have tried to search for »scope« in the C++ specification, but there are very many hits, and I gave up! Maybe some reader already knows the answer: It seems that the scope of »i« begins at the place of the comment in the following program. constexpr int f( int const * const p ){ return 2; } int main(){ constexpr int i/**/{ f( &i ) }; } Now, I would like to know the location in the C++ specification where this is specified. |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 06 12:17PM >>it's simple, because the rest of the program can always be written >>in a single line >Statement. One statement. Whenever one has multiple statements, one can use a compound statement (block) to merge them into a single statement. So, the requirement of »one statement« really is no requirement. |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 06 01:54PM >Well at least Christopher does not take the approach of answering a >question where the intent is obvious but the wording slightly amiss >with a pedantically correct but completely useless answer. If the intent is obvious, then maybe someone can write it down? »While sloppy writing does not invariably mean sloppy thinking, we've generally found the correlation to be strong -- and we have no use for sloppy thinkers. If you can't yet write competently, learn to.« Eric Raymond http://www.catb.org/~esr/faqs/hacker-howto.html#skills4 »I have never, ever, ever seen a great software developer who does not have amazing attention to detail.« http://www.softwarebyrob.com/articles/Personality_Traits_of_the_Best_Software_Developers.aspx |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 06 01:59PM >I think it is generally better to be helpful than to try to be "clever". When one does not know the meaning of words like »line« or »statement«, it is better to learn it (when posting into a technical programming newsgroup), than to accuse others. |
"Öö Tiib" <ootiib@hot.ee>: Mar 05 04:44PM -0800 On Friday, 6 March 2015 02:06:22 UTC+2, Stefan Ram wrote: > Maybe some reader already knows the answer: > It seems that the scope of »i« begins at the place > of the comment in the following program. Yes. > int main(){ constexpr int i/**/{ f( &i ) }; } > Now, I would like to know the location in the C++ > specification where this is specified. [basic.scope.block] Says that scope of your i starts from "point of declaration". [basic.scope.pdecl] tells that the "point of declaration" of your i is immediately after it and before its initializer. |
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