Re: std::string::assign range
On 3/6/2015 12:06 PM, Christopher Pisz wrote:
On 3/6/2015 10:54 AM, Christopher Pisz wrote:
On 3/6/2015 2:19 AM, Juha Nieminen wrote:
Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
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 ---
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 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.
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