<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	
	>
<channel>
	<title>
	Comments on: How to *Efficiently* Convert a String to an int in C++	</title>
	<atom:link href="https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/</link>
	<description>Jonathan Boccara&#039;s blog</description>
	<lastBuildDate>Tue, 31 Jul 2018 07:49:00 +0000</lastBuildDate>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.3</generator>
	<item>
		<title>
		By: Alexander Petrov		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1189</link>

		<dc:creator><![CDATA[Alexander Petrov]]></dc:creator>
		<pubDate>Tue, 31 Jul 2018 07:49:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1189</guid>

					<description><![CDATA[also see discussion at https://www.reddit.com/r/cpp/comments/92bkxp/how_to_efficiently_convert_a_string_to_an_int_in_c/]]></description>
			<content:encoded><![CDATA[<p>also see discussion at <a href="https://www.reddit.com/r/cpp/comments/92bkxp/how_to_efficiently_convert_a_string_to_an_int_in_c/" rel="nofollow ugc">https://www.reddit.com/r/cpp/comments/92bkxp/how_to_efficiently_convert_a_string_to_an_int_in_c/</a></p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: jft		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1184</link>

		<dc:creator><![CDATA[jft]]></dc:creator>
		<pubDate>Sun, 29 Jul 2018 09:00:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1184</guid>

					<description><![CDATA[A couple of questions have arisen over reading a file into memory (file_as_view() )

1) Will this process work with cin (ie can you redirect a file to stdin on the command line and read it in this way).

Yes - but a couple of changes are needed. ifstream&#038; should be replaced with istream&#038; and after the .seekg(), you need to test whether any data is present (ie that stdin has been redirected to a valid file). See the example below

2) Rather than using the allocated memory in the same function, can you return it so that it can be used elsewhere.

Yes. You could just return buffer (as unique_ptr is moveable but not copyable), but then you loose the size. You could return a pair of buffer and ifs.gcount() which gives you what you need, but perhaps the easiest is to return a string. Since c++17 string.data() is non-const so the referenced memory can be changed. So rather than allocating memory with make_unique(), create a string of the required size and use .data() as the parameter to .read(). Then the contents of the file are read directly into the string&#039;s buffer and the correct string size can be set after the read. This string will then be returned by move semantics. 

Consider

std::string readFile(std::istream&#038; ifs)
{
	ifs.clear();
	ifs.seekg(0, ifs.end);
 
	std::string fdata;
 
	if (ifs.tellg() &#062; 0) {
    		const auto fsz = static_cast(ifs.tellg());
 
    		fdata.assign(fsz, 0);
 
    		ifs.seekg(0);
    		ifs.read(fdata.data(), fsz);
    		fdata.resize(static_cast(ifs.gcount()));
	}
 
	return fdata;
}


3) What can you do if the file is too large to read all its contents into memory?
This is a good question. The obvious one, of course, is to use one of the other ways of reading data from a file (such as stream extraction) but this has the performance penalty. To benefit from the performance of memory read, there are a couple of ways. The easier is to read the file into memory in &#039;chunks&#039; into a buffer. Then extract the required data from the buffer and when you come to the end of the buffer, read the next &#039;chunk&#039; of the file into the buffer etc until the end of the file is reached. However, this has the slight drawback that the processing has to wait until the buffer is read when its end is reached. This small delay will probably be acceptable in most situations. However in very high performance situations, you need the maximum possible throughput. In this situation you use a method called &#039;double buffering&#039;. Essentially there are two buffers - and two threads. The idea is that the main thread processes the data in the primary buffer and whilst this is happening, the other thread is reading the next chunk of data into the other buffer. When the main thread comes to the end of the data in the primary buffer, the pointers to the two buffers are switched so that the main thread now processes data from the other buffer (now the primary buffer) without any wait and the other thread now reads the next chunk of data into the buffer that was primary. This reading and switching of buffers occurs until the actual end of file is reached. This is quite complicated so no code is shown here - it probably deserves an article of its own. There are also specific OS ways (such as Windows asynchronous file read etc).]]></description>
			<content:encoded><![CDATA[<p>A couple of questions have arisen over reading a file into memory (file_as_view() )</p>
<p>1) Will this process work with cin (ie can you redirect a file to stdin on the command line and read it in this way).</p>
<p>Yes &#8211; but a couple of changes are needed. ifstream&amp; should be replaced with istream&amp; and after the .seekg(), you need to test whether any data is present (ie that stdin has been redirected to a valid file). See the example below</p>
<p>2) Rather than using the allocated memory in the same function, can you return it so that it can be used elsewhere.</p>
<p>Yes. You could just return buffer (as unique_ptr is moveable but not copyable), but then you loose the size. You could return a pair of buffer and ifs.gcount() which gives you what you need, but perhaps the easiest is to return a string. Since c++17 string.data() is non-const so the referenced memory can be changed. So rather than allocating memory with make_unique(), create a string of the required size and use .data() as the parameter to .read(). Then the contents of the file are read directly into the string&#8217;s buffer and the correct string size can be set after the read. This string will then be returned by move semantics. </p>
<p>Consider</p>
<p>std::string readFile(std::istream&amp; ifs)<br />
{<br />
	ifs.clear();<br />
	ifs.seekg(0, ifs.end);</p>
<p>	std::string fdata;</p>
<p>	if (ifs.tellg() &gt; 0) {<br />
    		const auto fsz = static_cast(ifs.tellg());</p>
<p>    		fdata.assign(fsz, 0);</p>
<p>    		ifs.seekg(0);<br />
    		ifs.read(fdata.data(), fsz);<br />
    		fdata.resize(static_cast(ifs.gcount()));<br />
	}</p>
<p>	return fdata;<br />
}</p>
<p>3) What can you do if the file is too large to read all its contents into memory?<br />
This is a good question. The obvious one, of course, is to use one of the other ways of reading data from a file (such as stream extraction) but this has the performance penalty. To benefit from the performance of memory read, there are a couple of ways. The easier is to read the file into memory in &#8216;chunks&#8217; into a buffer. Then extract the required data from the buffer and when you come to the end of the buffer, read the next &#8216;chunk&#8217; of the file into the buffer etc until the end of the file is reached. However, this has the slight drawback that the processing has to wait until the buffer is read when its end is reached. This small delay will probably be acceptable in most situations. However in very high performance situations, you need the maximum possible throughput. In this situation you use a method called &#8216;double buffering&#8217;. Essentially there are two buffers &#8211; and two threads. The idea is that the main thread processes the data in the primary buffer and whilst this is happening, the other thread is reading the next chunk of data into the other buffer. When the main thread comes to the end of the data in the primary buffer, the pointers to the two buffers are switched so that the main thread now processes data from the other buffer (now the primary buffer) without any wait and the other thread now reads the next chunk of data into the buffer that was primary. This reading and switching of buffers occurs until the actual end of file is reached. This is quite complicated so no code is shown here &#8211; it probably deserves an article of its own. There are also specific OS ways (such as Windows asynchronous file read etc).</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: jft		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1183</link>

		<dc:creator><![CDATA[jft]]></dc:creator>
		<pubDate>Sat, 28 Jul 2018 11:34:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1183</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1182&quot;&gt;artana&lt;/a&gt;.

For MS VS2017 15.7.5 disabling sync has no effect on any of the timings - as standard streams aren&#039;t used. As far as I know (?), sync_with_stdio() only effects synchronisation between the standard input/output streams so that if enabled (by default) then cin/stdio, cerr/stderr and cout/stdout are synced so that code can switch between them without sync loss.]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1182">artana</a>.</p>
<p>For MS VS2017 15.7.5 disabling sync has no effect on any of the timings &#8211; as standard streams aren&#8217;t used. As far as I know (?), sync_with_stdio() only effects synchronisation between the standard input/output streams so that if enabled (by default) then cin/stdio, cerr/stderr and cout/stdout are synced so that code can switch between them without sync loss.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: artana		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1182</link>

		<dc:creator><![CDATA[artana]]></dc:creator>
		<pubDate>Fri, 27 Jul 2018 23:43:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1182</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1179&quot;&gt;Miguel Raggi&lt;/a&gt;.

Yes, msvc&#039;s stream performance has been shown to be awful in the past, and most of it is tied to syncing stdio and stream output.  If you disable the sync with sync_with_stdio(0) performance is several magnitudes better.]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1179">Miguel Raggi</a>.</p>
<p>Yes, msvc&#8217;s stream performance has been shown to be awful in the past, and most of it is tied to syncing stdio and stream output.  If you disable the sync with sync_with_stdio(0) performance is several magnitudes better.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Miguel Raggi		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1179</link>

		<dc:creator><![CDATA[Miguel Raggi]]></dc:creator>
		<pubDate>Fri, 27 Jul 2018 13:29:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1179</guid>

					<description><![CDATA[I think VS is probably doing something wrong with streams. They are way too slow. On my laptop, your string test with 50M with gcc 8.1.1 on linux takes 3.5s, not 40s. This is merely 7 times slower than from_chars (which takes half a second), not 50 as in your results.

BTW, Clang doesn&#039;t compile the code with an undefined reference to `__muloti4&#039;]]></description>
			<content:encoded><![CDATA[<p>I think VS is probably doing something wrong with streams. They are way too slow. On my laptop, your string test with 50M with gcc 8.1.1 on linux takes 3.5s, not 40s. This is merely 7 times slower than from_chars (which takes half a second), not 50 as in your results.</p>
<p>BTW, Clang doesn&#8217;t compile the code with an undefined reference to `__muloti4&#8242;</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: jft		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1169</link>

		<dc:creator><![CDATA[jft]]></dc:creator>
		<pubDate>Fri, 27 Jul 2018 10:45:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1169</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1164&quot;&gt;Bartlomiej Filipek&lt;/a&gt;.

VS2017.8 is supposed to fix many things with MS&#039;s existing VS2017 .7 that &#039;conforms to the c++17 standard&#039; with the introduction of the new parser. I&#039;ve got outstanding VS.7 c++ bugs that are &#039;fixed in .8&#039;. That&#039;s also supposed to allow Range v3 to compile, &#039;sort out&#039; the issues with constexpr and provide floating point ...
VS2017.8 is now at Preview 5!]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1164">Bartlomiej Filipek</a>.</p>
<p>VS2017.8 is supposed to fix many things with MS&#8217;s existing VS2017 .7 that &#8216;conforms to the c++17 standard&#8217; with the introduction of the new parser. I&#8217;ve got outstanding VS.7 c++ bugs that are &#8216;fixed in .8&#8217;. That&#8217;s also supposed to allow Range v3 to compile, &#8216;sort out&#8217; the issues with constexpr and provide floating point &#8230;<br />
VS2017.8 is now at Preview 5!</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: jft		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1168</link>

		<dc:creator><![CDATA[jft]]></dc:creator>
		<pubDate>Fri, 27 Jul 2018 09:37:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1168</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1167&quot;&gt;Nikita Alekseev&lt;/a&gt;.

If you manage to get some performance figures from tests, please do share.]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1167">Nikita Alekseev</a>.</p>
<p>If you manage to get some performance figures from tests, please do share.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Nikita Alekseev		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1167</link>

		<dc:creator><![CDATA[Nikita Alekseev]]></dc:creator>
		<pubDate>Fri, 27 Jul 2018 08:43:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1167</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1166&quot;&gt;jft&lt;/a&gt;.

Yeah, thanks I see that string_view is a temporary and will not outlive unique_ptr.

I&#039;m still interested how mmap would perform with string_view]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1166">jft</a>.</p>
<p>Yeah, thanks I see that string_view is a temporary and will not outlive unique_ptr.</p>
<p>I&#8217;m still interested how mmap would perform with string_view</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: jft		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1166</link>

		<dc:creator><![CDATA[jft]]></dc:creator>
		<pubDate>Fri, 27 Jul 2018 08:39:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1166</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1165&quot;&gt;Nikita Alekseev&lt;/a&gt;.

The memory will indeed be freed when returning from the function. However at that point the vector nos has been filled by as_from_chars() whose contents are not reliant upon the memory so there is no issue with string_view. Note that the vector nums is unused here and is a &#039;leftover&#039; from the original code from which this was text function was extracted. Doh! 

Yes, the allocation and de-allocation of the memory does have an overhead. However in fairness to the other methods it was felt that this is part of the process and so wasn&#039;t excluded.

&quot;Also have you considered using mmap with string_view?&quot;

No, not yet. The issue, as you mentioned above, is to avoid having a string_view which points to invalid memory. This isn&#039;t always as easy to ensure as it might seem.]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1165">Nikita Alekseev</a>.</p>
<p>The memory will indeed be freed when returning from the function. However at that point the vector nos has been filled by as_from_chars() whose contents are not reliant upon the memory so there is no issue with string_view. Note that the vector nums is unused here and is a &#8216;leftover&#8217; from the original code from which this was text function was extracted. Doh! </p>
<p>Yes, the allocation and de-allocation of the memory does have an overhead. However in fairness to the other methods it was felt that this is part of the process and so wasn&#8217;t excluded.</p>
<p>&#8220;Also have you considered using mmap with string_view?&#8221;</p>
<p>No, not yet. The issue, as you mentioned above, is to avoid having a string_view which points to invalid memory. This isn&#8217;t always as easy to ensure as it might seem.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Nikita Alekseev		</title>
		<link>https://www.fluentcpp.com/2018/07/27/how-to-efficiently-convert-a-string-to-an-int-in-c/#comment-1165</link>

		<dc:creator><![CDATA[Nikita Alekseev]]></dc:creator>
		<pubDate>Fri, 27 Jul 2018 07:37:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4030#comment-1165</guid>

					<description><![CDATA[Thank you for a nice insight!

Regarding the code snippet where you read file into a buffer and then create string_view: since you create buffer as a unique pointer, won&#039;t the memory be freed when returning from a function? This may result to a string_view which points to invalid memory. Also deallocation may slow down the benchmark.

Also have you considered using mmap with string_view?]]></description>
			<content:encoded><![CDATA[<p>Thank you for a nice insight!</p>
<p>Regarding the code snippet where you read file into a buffer and then create string_view: since you create buffer as a unique pointer, won&#8217;t the memory be freed when returning from a function? This may result to a string_view which points to invalid memory. Also deallocation may slow down the benchmark.</p>
<p>Also have you considered using mmap with string_view?</p>
]]></content:encoded>
		
			</item>
	</channel>
</rss>
