<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Ben J. Christensen &#187; Performance</title>
	<atom:link href="http://benjchristensen.com/category/performance/feed/" rel="self" type="application/rss+xml" />
	<link>http://benjchristensen.com</link>
	<description></description>
	<lastBuildDate>Fri, 25 May 2012 19:33:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='benjchristensen.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/a7bf6ab05bce6d423674b5a8bb676139?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Ben J. Christensen &#187; Performance</title>
		<link>http://benjchristensen.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://benjchristensen.com/osd.xml" title="Ben J. Christensen" />
	<atom:link rel='hub' href='http://benjchristensen.com/?pushpress=hub'/>
		<item>
		<title>Fault Tolerance in a High Volume, Distributed System</title>
		<link>http://benjchristensen.com/2012/03/01/fault-tolerance-in-a-high-volume-distributed-system/</link>
		<comments>http://benjchristensen.com/2012/03/01/fault-tolerance-in-a-high-volume-distributed-system/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 18:45:49 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[Production Problems]]></category>
		<category><![CDATA[distributed system]]></category>
		<category><![CDATA[fault tolerance]]></category>
		<category><![CDATA[high volume]]></category>
		<category><![CDATA[resiliency]]></category>
		<category><![CDATA[service oriented architecture]]></category>

		<guid isPermaLink="false">http://benjchristensen.com/?p=465</guid>
		<description><![CDATA[Originally posted on the Netflix Tech Blog: In an earlier post by Ben Schmaus, we shared the principles behind our circuit-breaker implementation. In that post, Ben discusses how the Netflix API interacts with dozens of systems in our service-oriented architecture, which makes the API inherently more vulnerable to any system failures or latencies underneath it [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=465&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Originally posted on the <a href="http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html">Netflix Tech Blog</a>:</p>
<hr />
<p>In an <a href="http://techblog.netflix.com/2011/12/making-netflix-api-more-resilient.html">earlier post</a> by <a href="http://twitter.com/schmaus">Ben Schmaus</a>, we shared the principles behind our circuit-breaker implementation. In that post, Ben discusses how the Netflix API interacts with dozens of systems in our service-oriented architecture, which makes the API inherently more vulnerable to any system failures or latencies underneath it in the stack. The rest of this post provides a more technical deep-dive into how our API and other systems isolate failure, shed load and remain resilient to failures.</p>
<p><span style="font-size:large;font-weight:bold;">Fault Tolerance is a Requirement, Not a Feature</span></p>
<p>The Netflix API receives more than 1 billion incoming calls per day which in turn fans out to several billion outgoing calls (averaging a ratio of 1:6) to dozens of underlying subsystems with peaks of over 100k dependency requests per second.<br />
<a href="http://benjchristensen.files.wordpress.com/2012/03/dependencies1.png"><img class="aligncenter size-full wp-image-469" title="" src="http://benjchristensen.files.wordpress.com/2012/03/dependencies1.png?w=800&h=727" alt="" width="800" height="727" border="0" /></a></p>
<p>This all occurs in the cloud across thousands of EC2 instances.</p>
<p>Intermittent failure is guaranteed with this many variables, even if every dependency itself has excellent availability and uptime.</p>
<p>Without taking steps to ensure fault tolerance, 30 dependencies each with 99.99% uptime would result in 2+ hours downtime/month (<span style="font-size:x-small;">99.99%<sup>30</sup> = 99.7% uptime = 2+ hours in a month</span>).</p>
<p>When a single API dependency fails at high volume with increased latency (causing blocked request threads) it can rapidly (seconds or sub-second) saturate all available Tomcat (or other container such as Jetty) request threads and take down the entire API.</p>
<p><a href="http://benjchristensen.files.wordpress.com/2012/03/dependencies3.png"><img class="aligncenter size-full wp-image-471" title="" src="http://benjchristensen.files.wordpress.com/2012/03/dependencies3.png?w=800&h=728" alt="" width="800" height="728" /></a></p>
<p>Thus, it is a requirement of high volume, high availability applications to build fault tolerance into their architecture and not expect infrastructure to solve it for them.</p>
<p><span style="font-size:large;font-weight:bold;">Netflix DependencyCommand Implementation</span></p>
<p>The service-oriented architecture at Netflix allows each team freedom to choose the best transport protocols and formats (XML, JSON, Thrift, Protocol Buffers, etc) for their needs so these approaches may vary across services.</p>
<p>In most cases the team providing a service also distributes a Java client library.</p>
<p>Because of this, applications such as API in effect treat the underlying dependencies as 3rd party client libraries whose implementations are &#8220;black boxes&#8221;. This in turn affects how fault tolerance is achieved.</p>
<p>In light of the above architectural considerations we chose to implement a solution that uses a combination of fault tolerance approaches:</p>
<ul>
<li><span style="font-size:100%;">network timeouts and retries</span></li>
<li><span style="font-size:100%;">separate threads on per-dependency thread pools</span></li>
<li><span style="font-size:100%;">semaphores (via a </span><a style="font-size:100%;" href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Semaphore.html#tryAcquire()">tryAcquire</a><span style="font-size:100%;">, not a blocking call)</span></li>
<li><span style="font-size:100%;">circuit breakers</span></li>
</ul>
<p>Each of these approaches to fault-tolerance has pros and cons but when combined together provide a comprehensive protective barrier between user requests and underlying dependencies.</p>
<p><a href="http://benjchristensen.files.wordpress.com/2012/03/faulttolerancetypes.png"><img class="aligncenter size-full wp-image-477" title="" src="http://benjchristensen.files.wordpress.com/2012/03/faulttolerancetypes.png?w=800&h=610" alt="" width="800" height="610" /></a></p>
<p>The Netflix DependencyCommand implementation wraps a network-bound dependency call with a preference towards executing in a separate thread and defines fallback logic which gets executed (step 8 in flow chart below) for any failure or rejection (steps 3, 4, 5a, 6b below) regardless of which type of fault tolerance (network or thread timeout, thread pool or semaphore rejection, circuit breaker) triggered it.</p>
<p><a href="http://benjchristensen.files.wordpress.com/2012/03/dependencycommands.png"><img class="aligncenter size-full wp-image-475" title="" src="http://benjchristensen.files.wordpress.com/2012/03/dependencycommands.png?w=800&h=325" alt="" width="800" height="325" /></a></p>
<p>We decided that the benefits of isolating dependency calls into separate threads outweighs the drawbacks (in most cases). Also, since the API is progressively <a href="http://techblog.netflix.com/2011/02/redesigning-netflix-api.html">moving towards increased concurrency</a> it was a win-win to achieve both fault tolerance and performance gains through concurrency with the same solution. In other words, the overhead of separate threads is being turned into a positive in many use cases by leveraging the concurrency to execute calls in parallel and speed up delivery of the Netflix experience to users.</p>
<p>Thus, most dependency calls now route through a separate thread-pool as the following diagram illustrates:</p>
<p><a href="http://benjchristensen.files.wordpress.com/2012/03/dependencies4.png"><img class="aligncenter size-full wp-image-472" title="" src="http://benjchristensen.files.wordpress.com/2012/03/dependencies4.png?w=800&h=1086" alt="" width="800" height="1086" /></a></p>
<p>If a dependency becomes latent (the worst-case type of failure for a subsystem) it can saturate all of the threads in its own thread pool, but Tomcat request threads will timeout or be rejected immediately rather than blocking.</p>
<p><a href="http://benjchristensen.files.wordpress.com/2012/03/dependencies6.png"><img class="aligncenter size-full wp-image-474" title="" src="http://benjchristensen.files.wordpress.com/2012/03/dependencies6.png?w=800&h=324" alt="" width="800" height="324" /></a></p>
<p>In addition to the isolation benefits and concurrent execution of dependency calls we have also leveraged the separate threads to enable request collapsing (automatic batching) to increase overall efficiency and reduce user request latencies.</p>
<p>Semaphores are used instead of threads for dependency executions known to not perform network calls (such as those only doing in-memory cache lookups) since the overhead of a separate thread is too high for these types of operations.</p>
<p>We also use semaphores to protect against non-trusted fallbacks. Each DependencyCommand is able to define a fallback function (discussed more below) which is performed on the calling user thread and should not perform network calls. Instead of trusting that all implementations will correctly abide to this contract, it too is protected by a semaphore so that if an implementation is done that involves a network call and becomes latent, the fallback itself won&#8217;t be able to take down the entire app as it will be limited in how many threads it will be able to block.</p>
<p>Despite the use of separate threads with timeouts, we continue to aggressively set timeouts and retries at the network level (through interaction with client library owners, monitoring, audits etc).</p>
<p>The timeouts at the DependencyCommand threading level are the first line of defense regardless of how the underlying dependency client is configured or behaving but the network timeouts are still important otherwise highly latent network calls could fill the dependency thread-pool indefinitely.</p>
<p>The tripping of circuits kicks in when a DependencyCommand has passed a certain threshold of error (such as 50% error rate in a 10 second period) and will then reject all requests until health checks succeed.</p>
<p>This is used primarily to release the pressure on underlying systems (i.e. shed load) when they are having issues and reduce the user request latency by failing fast (or returning a fallback) when we know it is likely to fail instead of making every user request wait for the timeout to occur.</p>
<p><span style="font-size:large;font-weight:bold;">How do we respond to a user request when failure occurs?</span></p>
<p>In each of the options described above a timeout, thread-pool or semaphore rejection, or short-circuit will result in a request not retrieving the optimal response for our customers.</p>
<p>An immediate failure (&#8220;fail fast&#8221;) throws an exception which causes the app to shed load until the dependency returns to health. This is preferable to requests &#8220;piling up&#8221; as it keeps Tomcat request threads available to serve requests from healthy dependencies and enables rapid recovery once failed dependencies recover.</p>
<p>However, there are often several preferable options for providing responses in a &#8220;fallback mode&#8221; to reduce impact of failure on users. Regardless of what causes a failure and how it is intercepted (timeout, rejection, short-circuited etc) the request will always pass through the fallback logic (step 8 in flow chart above) before returning to the user to give a DependencyCommand the opportunity to do something other than &#8220;fail fast&#8221;.</p>
<p>Some approaches to fallbacks we use are, in order of their impact on the user experience:</p>
<ul>
<li><span style="font-size:100%;">Cache: Retrieve data from local or remote caches if the realtime dependency is unavailable, even if the data ends up being stale</span></li>
<li><span style="font-size:100%;">Eventual Consistency: Queue writes (such as in </span><a style="font-size:100%;" href="http://aws.amazon.com/sqs/">SQS</a><span style="font-size:100%;">) to be persisted once the dependency is available again</span></li>
<li><span style="font-size:100%;">Stubbed Data: Revert to default values when personalized options can&#8217;t be retrieved</span></li>
<li><span style="font-size:100%;">Empty Response (&#8220;Fail Silent&#8221;): Return a null or empty list which UIs can then ignore</span></li>
</ul>
<p>All of this work is to maintain maximum uptime for our users while maintaining the maximum number of features for them to enjoy the richest Netflix experience possible. As a result, our goal is to have the fallbacks deliver responses as close to what the actual dependency would deliver.</p>
<p><span style="font-size:large;font-weight:bold;">Example Use Case</span></p>
<p>Following is an example of how threads, network timeouts and retries combine:</p>
<p><a href="http://benjchristensen.files.wordpress.com/2012/03/faulttoleranceexampleconfig.png"><img class="aligncenter size-full wp-image-476" title="" src="http://benjchristensen.files.wordpress.com/2012/03/faulttoleranceexampleconfig.png?w=800&h=675" alt="" width="800" height="675" /></a></p>
<p>The above diagram shows an example configuration where the dependency has no reason to hit the 99.5th percentile and thus cuts it short at the network timeout layer and immediately retries with the expectation to get median latency most of the time, and accomplish this all within the 300ms thread timeout.</p>
<p>If the dependency has legitimate reasons to sometimes hit the 99.5th percentile (i.e. cache miss with lazy generation) then the network timeout will be set higher than it, such as at 325ms with 0 or 1 retries and the thread timeout set higher (350ms+).</p>
<p>The threadpool is sized at 10 to handle a burst of 99th percentile requests, but when everything is healthy this threadpool will typically only have 1 or 2 threads active at any given time to serve mostly 40ms median calls.</p>
<p>When configured correctly a timeout at the DependencyCommand layer should be rare, but the protection is there in case something other than network latency affects the time, or the combination of connect+read+retry+connect+read in a worst case scenario still exceeds the configured overall timeout.</p>
<p>The aggressiveness of configurations and tradeoffs in each direction are different for each dependency.</p>
<p>Configurations can be changed in realtime as needed as performance characteristics change or when problems are found all without risking the taking down of the entire app if problems or misconfigurations occur.</p>
<p><span style="font-size:large;font-weight:bold;">Conclusion</span></p>
<p>The approaches discussed in this post have had a dramatic effect on our ability to tolerate and be resilient to system, infrastructure and application level failures without impacting (or limiting impact to) user experience.</p>
<p>Despite the success of this new DependencyCommand resiliency system over the past 8 months, there is still a lot for us to do in improving our fault tolerance strategies and performance, especially as we continue to add functionality, devices, customers and international markets.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/465/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/465/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/465/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/465/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/465/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/465/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/465/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/465/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/465/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/465/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/465/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/465/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/465/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/465/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=465&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2012/03/01/fault-tolerance-in-a-high-volume-distributed-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2012/03/dependencies1.png" medium="image" />

		<media:content url="http://benjchristensen.files.wordpress.com/2012/03/dependencies3.png" medium="image" />

		<media:content url="http://benjchristensen.files.wordpress.com/2012/03/faulttolerancetypes.png" medium="image" />

		<media:content url="http://benjchristensen.files.wordpress.com/2012/03/dependencycommands.png" medium="image" />

		<media:content url="http://benjchristensen.files.wordpress.com/2012/03/dependencies4.png" medium="image" />

		<media:content url="http://benjchristensen.files.wordpress.com/2012/03/dependencies6.png" medium="image" />

		<media:content url="http://benjchristensen.files.wordpress.com/2012/03/faulttoleranceexampleconfig.png" medium="image" />
	</item>
		<item>
		<title>WebService Performance on EC2 Instances</title>
		<link>http://benjchristensen.com/2012/01/05/webservice-performance-on-ec2-instances/</link>
		<comments>http://benjchristensen.com/2012/01/05/webservice-performance-on-ec2-instances/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 03:24:50 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[amazon ec2]]></category>
		<category><![CDATA[performance efficiency]]></category>

		<guid isPermaLink="false">http://benjchristensen.com/?p=443</guid>
		<description><![CDATA[As part of a cost/performance analysis of Amazon EC2 instances I wrote a very simple Java webapp to allow simple comparison benchmarking. The webapp runs in Tomcat and has a servlet which returns a JSON response after looping to generate the JSON to cause CPU computation time as if the service were doing real work. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=443&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As part of a cost/performance analysis of <a href="http://aws.amazon.com/ec2/instance-types/">Amazon EC2 instances</a> I wrote a <a href="https://github.com/benjchristensen/WSPerformanceTest">very simple Java webapp</a> to allow simple comparison benchmarking.</p>
<p>The webapp runs in Tomcat and has a <a href="https://github.com/benjchristensen/WSPerformanceTest/blob/master/src/com/wsperformancetest/ComputationalSimulationService.java">servlet</a> which returns a JSON response after looping to generate the JSON to cause CPU computation time as if the service were doing real work. It results in a lot of iteration and string creation activity – things web services do a lot of.</p>
<p>ApacheBenchmark (ab) was used as the test client to simulate traffic and capture statistics.</p>
<p>The instance types tested were <a href="https://github.com/benjchristensen/WSPerformanceTest/blob/master/testResults/2012_January5_EC2_Testing/machine_information_ec2_m2.2xlarge.txt">m2.2xlarge</a>, <a href="https://github.com/benjchristensen/WSPerformanceTest/blob/master/testResults/2012_January5_EC2_Testing/machine_information_ec2_m2.4xlarge.txt">m2.4xlarge</a>, <a href="https://github.com/benjchristensen/WSPerformanceTest/blob/master/testResults/2012_January5_EC2_Testing/machine_information_ec2_cc1.4xlarge.txt">cc1.4xlarge</a>, and <a href="https://github.com/benjchristensen/WSPerformanceTest/blob/master/testResults/2012_January5_EC2_Testing/machine_information_ec2_cc2.8xlarge.txt">cc2.8xlarge</a>.</p>
<p>The tests determined that the cc2.8xlarge instance type – though the most expensive by unit – is potentially the most cost effective type to use when serving large volume traffic involving a cluster of servers.</p>
<p>The cost to serve 1000 requests/second at a response time of approximately 18ms for each instance type is:</p>
<ul>
<li>m2.2xlarge: $1.98</li>
<li>m2.4xlarge: $2.48</li>
<li>cc1.4xlarge: $1.36</li>
<li><strong>cc2.8xlarge: $1.19</strong></li>
</ul>
<p>Of course, this test is very simplistic and ignores a wide variety of variables, but it demonstrates that the cc1 and cc2 boxes are well worth the time to evaluate for production application usage for achieving cost/performance efficiency.</p>
<p>The following graphs show the test results that were used to calculate the above costs.</p>
<p><strong>Results per Second with Increasing Concurrency</strong></p>
<p>This demonstrates how the 32 CPU cores on the cc2.8xlarge enable significantly higher throughput.</p>
<p><img class="aligncenter size-full wp-image-446" title="requests_per_second_with_increasing_concurrency" src="http://benjchristensen.files.wordpress.com/2012/01/requests_per_second_with_increasing_concurrency.png?w=800&h=386" alt="" width="800" height="386" /></p>
<p><strong>Time per Request (ms) with Increasing Concurrency</strong></p>
<p>This shows how the response time degrades with increasing thread counts and how the larger boxes (particularly the cc2) scale better.</p>
<p><img class="aligncenter size-full wp-image-447" title="time_per_request_with_increasing_concurrency" src="http://benjchristensen.files.wordpress.com/2012/01/time_per_request_with_increasing_concurrency.png?w=800&h=372" alt="" width="800" height="372" /></p>
<p><strong>Spreadsheet</strong></p>
<p>This screenshot of the spreadsheet shows the cost calculations at each level of concurrency.</p>
<p>The hi-lighted green is considered the optimal &#8220;ceiling&#8221; beyond which performance degrades and throughput plateaus. This point is considered the high-water-mark that can be used to determine the number of machines in a cluster needed to serve a given amount of traffic and thus allow comparison of different machines.</p>
<p><img class="aligncenter size-full wp-image-444" title="ec2-performance-data" src="http://benjchristensen.files.wordpress.com/2012/01/ec2-performance-data.png?w=800&h=607" alt="" width="800" height="607" /></p>
<p><strong>Price per 1000 Requests per Second with Increasing Concurrency</strong></p>
<p>This scatter chart shows the cost to serve 1000 requests per second at increasing levels of concurrency on each instance type.</p>
<p><img class="aligncenter size-full wp-image-445" title="price_with_increasing_concurrency" src="http://benjchristensen.files.wordpress.com/2012/01/price_with_increasing_concurrency.png?w=800" alt=""   /></p>
<p>Overall, the performance of the cc1 and cc2 boxes are impressive and their cost/performance appears to be far better than the m2 instances.</p>
<p>The raw results of the tests can be found on <a href="https://github.com/benjchristensen/WSPerformanceTest/tree/master/testResults/2012_January5_EC2_Testing">Github</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/443/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=443&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2012/01/05/webservice-performance-on-ec2-instances/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2012/01/requests_per_second_with_increasing_concurrency.png" medium="image">
			<media:title type="html">requests_per_second_with_increasing_concurrency</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2012/01/time_per_request_with_increasing_concurrency.png" medium="image">
			<media:title type="html">time_per_request_with_increasing_concurrency</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2012/01/ec2-performance-data.png" medium="image">
			<media:title type="html">ec2-performance-data</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2012/01/price_with_increasing_concurrency.png" medium="image">
			<media:title type="html">price_with_increasing_concurrency</media:title>
		</media:content>
	</item>
		<item>
		<title>AtomicCircularArray Wins My Concurrency Throughput Test</title>
		<link>http://benjchristensen.com/2011/10/08/atomiccirculararray/</link>
		<comments>http://benjchristensen.com/2011/10/08/atomiccirculararray/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 05:42:41 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://benjchristensen.com/?p=399</guid>
		<description><![CDATA[I recently made several implementations of a RollingNumber (allowing a sum to be calculated over a 10 second period with 1 second increments with continual updates) to determine what would perform best under high-concurrency. In my case, concurrency means 4-8000 writes/second from hundreds of threads on an 8-core machine and only a handful of reads [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=399&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently made several implementations of a RollingNumber (allowing a sum to be calculated over a 10 second period with 1 second increments with continual updates) to determine what would perform best under high-concurrency.</p>
<p>In my case, concurrency means 4-8000 writes/second from hundreds of threads on an 8-core machine and only a handful of reads per second.</p>
<p>In the end, a circular-array (using AtomicReferenceArray internally) won my throughput tests and also achieved my side goal of being non-blocking.</p>
<p>The <a href="https://github.com/benjchristensen/RollingNumberConcurrencyTesting">code is on GitHub</a> and the winning implementation is <a href="https://github.com/benjchristensen/RollingNumberConcurrencyTesting/blob/master/src/RollingNumberViaTryLockWithAtomicCircularArray.java">RollingNumberViaTryLockWithAtomicCircularArray</a>.</p>
<p>Note that this code is NOT what I would deploy in production, since I forced each implementation to comply to the same interface so they could all be run by my test-harness.</p>
<p>However, a modified version of RollingNumberViaTryLockWithAtomicCircularArray is being run in production processing billions of writes per day.</p>
<p>Another aspect of the test is the use of ReentrantLock.tryLock() instead of a synchronized block. The tryLock() works well in this use-case, allowing only 1 thread to get the lock and routing all others around it instead of blocking them.</p>
<p><strong>Test Results</strong></p>
<p>Here are charts (higher is better) showing the differences in performance between implementations on two different machines:</p>
<p><strong>MacBook Pro 2.2GHz Intel Core i7, 8GB Memory, SSD Drive, OSX Lion 10.7.1</strong></p>
<pre>$ uname -a
Darwin 11.1.0 Darwin Kernel Version 11.1.0: Tue Jul 26 16:07:11 PDT 2011; root:xnu-1699.22.81~1/RELEASE_X86_64 x86_64

$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)</pre>
<p>The winner is the blue bar which is the highest.</p>
<p><a href="http://benjchristensen.files.wordpress.com/2011/10/concurrent_throughput_rollingnumber_macbookpro.png"><img class="aligncenter size-full wp-image-400" title="concurrent_throughput_rollingnumber_macbookpro" src="http://benjchristensen.files.wordpress.com/2011/10/concurrent_throughput_rollingnumber_macbookpro.png?w=800&h=599" alt="" width="800" height="599" /></a></p>
<p><strong>Amazon EC2 m2.4xlarge</strong><br />
High-Memory Quadruple Extra Large Instance 68.4 GB of memory, 26 EC2 Compute Units (8 virtual cores with 3.25 EC2 Compute Units each), 1690 GB of local instance storage, 64-bit platform</p>
<pre>$ uname -a
Linux 2.6.21.7-2.ec2.v1.3.fc8xen #1 SMP Sat Sep 25 01:16:50 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

$ /usr/java/latest/bin/java -version
java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)</pre>
<p>The winner is the orange bar which is the highest.</p>
<p><a href="http://benjchristensen.files.wordpress.com/2011/10/concurrent_throughput_rollingnumber_ec2.png"><img class="aligncenter size-full wp-image-404" title="concurrent_throughput_rollingnumber_ec2" src="http://benjchristensen.files.wordpress.com/2011/10/concurrent_throughput_rollingnumber_ec2.png?w=800&h=548" alt="" width="800" height="548" /></a></p>
<p><strong>Running the Test</strong></p>
<p>You can run the test using an <a href="https://github.com/downloads/benjchristensen/RollingNumberConcurrencyTesting/RollingNumberThroughputTest.jar">executable JAR</a> with the command:</p>
<pre>
java -Xmx1g -jar RollingNumberThroughputTest.jar
</pre>
<p>The test also validates that the code does what it should and is able to find non-thread-safe implementations by looking for incorrect math caused by concurrency bugs.</p>
<p><strong>Conclusion</strong></p>
<p>I found it very interesting how differently the results were on the 2 machines (operating systems and CPUs are very different, the JVM implementations are also different). In both cases though the AtomicCircularArray performed better, far better on the EC2 instance running the Sun JVM.</p>
<p>These tests provided me with the data to choose AtomicCircularArray and as mentioned above it is similar to what I&#8217;m now using in production.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/399/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=399&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2011/10/08/atomiccirculararray/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2011/10/concurrent_throughput_rollingnumber_macbookpro.png" medium="image">
			<media:title type="html">concurrent_throughput_rollingnumber_macbookpro</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2011/10/concurrent_throughput_rollingnumber_ec2.png" medium="image">
			<media:title type="html">concurrent_throughput_rollingnumber_ec2</media:title>
		</media:content>
	</item>
		<item>
		<title>Statistics for Why Web Performance Matters</title>
		<link>http://benjchristensen.com/2009/10/02/statistics-for-why-web-performance-matters/</link>
		<comments>http://benjchristensen.com/2009/10/02/statistics-for-why-web-performance-matters/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 22:29:55 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://benjchristensen.com/?p=283</guid>
		<description><![CDATA[Following are some good posts with further evidence of the impact of webpage/webapp responsiveness to the user experience, amount of usage and ultimately revenue. Good introductory quote to the external links and images shown below: There’s no longer any debate. There’s reliable, reproducible evidence that web page latency is directly tied to the bottom line. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=283&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Following are some good posts with further evidence of the impact of webpage/webapp responsiveness to the user experience, amount of usage and ultimately revenue.</p>
<p>Good introductory quote to the external links and images shown below:</p>
<blockquote><p>There’s no longer any debate. There’s reliable, reproducible evidence that web page latency is directly tied to the bottom line. At Velocity, Microsoft, Google and Shopzilla made this abundantly clear in a series of awesome presentations: detailed, controlled testing proves that slower pages hurt the bottom line. In Google’s case, adding delay reduces the average number of searches a visitor does each day even after the delay is removed.</p></blockquote>
<p>Regarding &#8220;smaller scale&#8221; sites more typical than Google and Bing:</p>
<blockquote><p>The results of their analysis show how significant a reduction in page latency can be. In addition to reducing bounce rates, and increasing pages per visit &amp; time on site, t<strong>hey found a 16.07% increase in conversion rates and a 5.50% increase in average order value.</strong> &#8211; <a href="http://radar.oreilly.com/2009/10/watching-websites.html">http://radar.oreilly.com/2009/10/watching-websites.html</a></p></blockquote>
<p>External Links:</p>
<p><a href="http://radar.oreilly.com/2009/10/watching-websites.html">http://radar.oreilly.com/2009/10/watching-websites.html</a><br />
<a href="http://radar.oreilly.com/2009/07/velocity-making-your-site-fast.html">http://radar.oreilly.com/2009/07/velocity-making-your-site-fast.html</a><br />
<a href="http://www.watchingwebsites.com/archives/proof-that-speeding-up-websites-improves-online-business">http://www.watchingwebsites.com/archives/proof-that-speeding-up-websites-improves-online-business</a></p>
<p>Good <a href="http://www.watchingwebsites.com/~/www.watchingwebsites.com/web/content/wp-content/uploads//2009/09/watchingwebsites-perf-and-analytics.pdf">summary PDF</a> showing metrics of performance impact.</p>
<p><a href="http://benjchristensen.files.wordpress.com/2009/10/conversion-rate-and-order-value.png"><img src="http://benjchristensen.files.wordpress.com/2009/10/conversion-rate-and-order-value.png?w=800" alt="conversion-rate-and-order-value" title="conversion-rate-and-order-value"   class="alignnone size-full wp-image-284" /></a></p>
<p><a href="http://benjchristensen.files.wordpress.com/2009/10/bing-delayimpact.png"><img src="http://benjchristensen.files.wordpress.com/2009/10/bing-delayimpact.png?w=800" alt="bing-delayimpact" title="bing-delayimpact"   class="alignnone size-full wp-image-285" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/283/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=283&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2009/10/02/statistics-for-why-web-performance-matters/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2009/10/conversion-rate-and-order-value.png" medium="image">
			<media:title type="html">conversion-rate-and-order-value</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2009/10/bing-delayimpact.png" medium="image">
			<media:title type="html">bing-delayimpact</media:title>
		</media:content>
	</item>
		<item>
		<title>Initial Impressions on Ruby Performance</title>
		<link>http://benjchristensen.com/2009/08/18/initial-impressions-on-ruby-performance/</link>
		<comments>http://benjchristensen.com/2009/08/18/initial-impressions-on-ruby-performance/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 04:09:37 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://benjchristensen.com/?p=261</guid>
		<description><![CDATA[I&#8217;ve spent the past day playing with Ruby and decided to test some basic performance &#8211; iterating and string parsing &#8211; to get an idea of what the performance is really like. Ruby is not doing so well in my tests. Note to Ruby Experts: If anyone can demonstrate what I&#8217;m doing wrong in my [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=261&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spent the past day playing with Ruby and decided to test some basic performance &#8211; iterating and string parsing &#8211; to get an idea of what the performance is really like.</p>
<p>Ruby is not doing so well in my tests.</p>
<p><em>Note to Ruby Experts: If anyone can demonstrate what I&#8217;m doing wrong in my code or testing, I would love to be corrected.</em></p>
<p>My approach was to write the exact same code in Java and Ruby that loads up a file, reads each lines, tokenizes it into words using whitespace as the delimiter and counts up the tokens.</p>
<p>This avoids network or database IO and other external resources &#8211; except the filesystem which I don&#8217;t consider a significant variable in the test.</p>
<p>Further testing I&#8217;m planning on doing will test Rails, multi-threading and other common things I do in my apps.</p>
<p><a href="http://benjchristensen.files.wordpress.com/2009/08/picture-31.png"><img class="alignnone size-full wp-image-272" title="Picture 3" src="http://benjchristensen.files.wordpress.com/2009/08/picture-31.png?w=800" alt="Picture 3"   /></a></p>
<p>On my laptop, a MacBook Pro 2.53Ghz Core 2 Duo with 4GB memory, the average times are:</p>
<ul>
<li>Ruby 1.8.6 app: 8022ms</li>
<li>Java 5 app: 2986ms</li>
<li>Java 6 app: 1443ms</li>
</ul>
<p><strong>Source Code</strong></p>
<ul>
<li><a href="http://benjchristensen.files.wordpress.com/2009/08/filereadparse-java.doc">FileReadParse.java</a></li>
<li><a href="http://benjchristensen.files.wordpress.com/2009/08/file_read_parse-rb.doc">file_read_parse.rb</a></li>
</ul>
<p>After downloading, strip the .doc ending off of the files.</p>
<p><strong>Program Output</strong></p>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:407px;width:1px;height:1px;">macbook-pro:src benjc$ /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java FileReadParse</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:407px;width:1px;height:1px;">Starting to read file&#8230;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:407px;width:1px;height:1px;">The number of tokens is: 7764115</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:407px;width:1px;height:1px;">It took 1502 ms</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:407px;width:1px;height:1px;">macbook-pro:performance benjc$ ruby file_read_parse.rb</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:407px;width:1px;height:1px;">Starting to read file &#8230;</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:407px;width:1px;height:1px;">The number of tokens is: 7764115</div>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:407px;width:1px;height:1px;">It took 7999.955 ms</div>
<p>macbook-pro:src benjc$ /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java FileReadParse</p>
<p>Starting to read file&#8230;</p>
<p>The number of tokens is: 7764115</p>
<p>It took 1502 ms</p>
<p>macbook-pro:performance benjc$ ruby file_read_parse.rb</p>
<p>Starting to read file &#8230;</p>
<p>The number of tokens is: 7764115</p>
<p>It took 7999.955 ms</p>
<p><span style="font-family:Georgia, 'Times New Roman', 'Bitstream Charter', Times, 0;"><span style="font-size:small;"><br />
</span></span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/261/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=261&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2009/08/18/initial-impressions-on-ruby-performance/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2009/08/picture-31.png" medium="image">
			<media:title type="html">Picture 3</media:title>
		</media:content>
	</item>
		<item>
		<title>Speed of Thought</title>
		<link>http://benjchristensen.com/2009/06/26/speed-of-thought/</link>
		<comments>http://benjchristensen.com/2009/06/26/speed-of-thought/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 20:29:49 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://benjchristensen.wordpress.com/?p=118</guid>
		<description><![CDATA[I&#8217;ve focused on performance for several years in my server-side and web application development &#8211; as much as I&#8217;ve been able to fit into the timelines. It has involved digging into minute details of Java and JVM tuning that rarely get explored by most java developers (from what I can tell anyways) and focusing on [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=118&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve focused on performance for several years in my server-side and web application development &#8211; as much as I&#8217;ve been able to fit into the timelines. It has involved digging into minute details of Java and JVM tuning that rarely get explored by most java developers (from what I can tell anyways) and focusing on tuning the CSS, images, caching, GZIP and other settings of the front-end. It has generally paid off. Today my team operates servers processing millions of complex, dynamic, uncacheable web service transactions completing on average in around 250ms each (server side, not including network transport to client). I believe with further investment we could improve that even more.</p>
<p>I have read comments from companies such as Google and Amazon how the performance of an application can dramatically affect how much people use it. I agree. The slightest friction in searching makes me search less, or shop less, etc.</p>
<p>This past week I&#8217;ve been using the new iPhone 3GS which is at least 2x faster than the previous iPhone 2G I had. In some cases it&#8217;s 4x and 6x faster.</p>
<p>I already used the iPhone a lot. The increase in speed has further reduced the &#8220;friction&#8221; of use to the point that if I even have a thought of quickly looking something up or performing some other action, I am much more likely to do it.</p>
<p>On my last iPhone, I consciously chose to not bother at certain times because of the time it would take. Yes, I&#8217;m talking in seconds and even milliseconds here &#8212; but when it&#8217;s a &#8220;thought&#8221;, if the tool doesn&#8217;t work at the same speed, then it&#8217;s friction. Same goes for another application I use which involves looking up reference materials and documents. Before I kind of had to avoid &#8220;flipping around&#8217; while someone was referring to things. It was actually faster to use the paper documents. Now, I can keep up or be faster with my iPhone than the paper version &#8216;users&#8217;. Therefore it encourages use.</p>
<p>The new user experience of using the iPhone 3GS, so significantly improved just by the performance improvement, has reminded me as a developer and architect how critical it is to design, plan for and develop to achieve high performance. Functionality isn&#8217;t enough &#8212; we should be aiming for the &#8220;speed of thought&#8221;.</p>
<p>Interestingly, Google has just launched a new site just for &#8220;<a href="http://code.google.com/speed/">speeding up the web</a>&#8220;.</p>
<p>The following video shows &#8220;the experts&#8221; talking about how the human mind perceives changes of 100ms (one tenth of a second).</p>
<span style="text-align:center; display: block;"><a href="http://benjchristensen.com/2009/06/26/speed-of-thought/"><img src="http://img.youtube.com/vi/aXJklICrFJI/2.jpg" alt="" /></a></span>
<p>It&#8217;s my belief that this isn&#8217;t just a &#8220;nice to have&#8221; feature. If a product, service or application wants to be adopted and deemed &#8220;necessary&#8221; by its users, its performance must reduce friction as much as technically feasible to the point where it approaches or achieves &#8220;speed of thought&#8221;.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/118/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=118&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2009/06/26/speed-of-thought/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>
	</item>
		<item>
		<title>Java JDK 1.5 vs 1.6 Performance</title>
		<link>http://benjchristensen.com/2009/02/12/java-jdk-15-vs-16-performance/</link>
		<comments>http://benjchristensen.com/2009/02/12/java-jdk-15-vs-16-performance/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 00:19:06 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://benjchristensen.wordpress.com/?p=91</guid>
		<description><![CDATA[In a benchmarking of our server software I found about a 34% speed improvement (if my math is correct) on using JDK 1.6.0_12 over JDK 1.5.0_17.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=91&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In a benchmarking of our server software I found about a 34% speed improvement (if my math is correct) on using JDK 1.6.0_12 over JDK 1.5.0_17.</p>
<p><img class="alignnone size-full wp-image-92" title="picture-8" src="http://benjchristensen.files.wordpress.com/2009/02/picture-8.png?w=800" alt="picture-8"   /></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/91/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=91&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2009/02/12/java-jdk-15-vs-16-performance/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>

		<media:content url="http://benjchristensen.files.wordpress.com/2009/02/picture-8.png" medium="image">
			<media:title type="html">picture-8</media:title>
		</media:content>
	</item>
		<item>
		<title>ConcurrentHashMap vs HashMap</title>
		<link>http://benjchristensen.com/2008/10/17/concurrenthashmap-vs-hashmap/</link>
		<comments>http://benjchristensen.com/2008/10/17/concurrenthashmap-vs-hashmap/#comments</comments>
		<pubDate>Fri, 17 Oct 2008 20:07:11 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://benjchristensen.wordpress.com/?p=72</guid>
		<description><![CDATA[A simple test of performance for ConcurrentHashMap. The insert is only a little slower, but the retrieval is 3x slower in this quick and dirty single-threaded test.   TimeUtil timer = new TimeUtil();         timer.start();         HashMap map = new HashMap();         for (int i = [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=72&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A simple test of performance for ConcurrentHashMap.</p>
<p>The insert is only a little slower, but the retrieval is 3x slower in this quick and dirty single-threaded test.</p>
<p> </p>
<p>TimeUtil timer = <span>new</span> TimeUtil();</p>
<p>        timer.start();</p>
<p>        HashMap map = <span>new</span> HashMap();</p>
<p>        <span>for</span> (<span>int</span> i = 0; i &lt; 1000000; i++) {</p>
<p>            map.put(i, i);</p>
<p>        }</p>
<p>        timer.printCurrent();</p>
<p>        </p>
<p>        timer.start();</p>
<p>        ConcurrentHashMap cmap = <span>new</span> ConcurrentHashMap();</p>
<p>        <span>for</span> (<span>int</span> i = 0; i &lt; 1000000; i++) {</p>
<p>            cmap.put(i, i);</p>
<p>        }</p>
<p>        timer.printCurrent();</p>
<p>        </p>
<p> </p>
<p>        </p>
<p>        timer = <span>new</span> TimeUtil();</p>
<p>        timer.start();</p>
<p>        map = <span>new</span> HashMap();</p>
<p>        <span>for</span> (<span>int</span> i = 0; i &lt; 1000000; i++) {</p>
<p>            map.get(i);</p>
<p>        }</p>
<p>        timer.printCurrent();</p>
<p>        </p>
<p>        timer.start();</p>
<p>        cmap = <span>new</span> ConcurrentHashMap();</p>
<p>        <span>for</span> (<span>int</span> i = 0; i &lt; 1000000; i++) {</p>
<p>            cmap.get(i);</p>
<p>        }</p>
<p>        timer.printCurrent();</p>
<p> </p>
<p>Action completed in: 458 ms 0.458 seconds</p>
<p>Action completed in: 574 ms 0.574 seconds</p>
<p>Action completed in: 30 ms 0.03 seconds</p>
<p>Action completed in: 113 ms 0.113 seconds</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/72/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=72&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2008/10/17/concurrenthashmap-vs-hashmap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>
	</item>
		<item>
		<title>MySQL JDBC Memory Usage on Large ResultSet</title>
		<link>http://benjchristensen.com/2008/05/27/mysql-jdbc-memory-usage-on-large-resultset/</link>
		<comments>http://benjchristensen.com/2008/05/27/mysql-jdbc-memory-usage-on-large-resultset/#comments</comments>
		<pubDate>Tue, 27 May 2008 21:23:20 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://benjchristensen.wordpress.com/?p=59</guid>
		<description><![CDATA[I recently came across the problem of large resultsets being pulled into a java app via MySQL JDBC. I had dealt with this years ago but forgotten about it. The test case below shows how the entire ResultSet is buffered in memory by default &#8212; which can be a &#8220;very bad thing&#8221; when dealing with [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=59&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently came across the problem of large resultsets being pulled into a java app via MySQL JDBC. I had dealt with this years ago but forgotten about it.</p>
<p>The test case below shows how the entire ResultSet is buffered in memory by default &#8212; which can be a &#8220;very bad thing&#8221; when dealing with hundreds or thousands of megabytes of data when it&#8217;s intended to be processed row by row.</p>
<p><strong>Using mysql-connector-java-3.1.12-bin.jar and a JDK 5 with 32MB heap:</strong></p>
<p style="padding-left:60px;">ET-COMMONS INFO: JVM MEMORY MONITOR =&gt; Total: 33  Used: 1  Free: 32</p>
<p style="padding-left:60px;">Retrieving data &#8230;</p>
<p style="padding-left:60px;">Ran out of memory at row: 0</p>
<p style="padding-left:60px;">java.lang.OutOfMemoryError: Java heap space</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.ByteArrayBuffer.getBytes(<span>ByteArrayBuffer.java:128</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.ByteArrayBuffer.readLenByteArray(<span>ByteArrayBuffer.java:248</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.nextRow(<span>MysqlIO.java:1304</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.readSingleRowSet(<span>MysqlIO.java:2272</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.getResultSet(<span>MysqlIO.java:423</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(<span>MysqlIO.java:1962</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.readAllResults(<span>MysqlIO.java:1385</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.sqlQueryDirect(<span>MysqlIO.java:1728</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.Connection.execSQL(<span>Connection.java:2988</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.Connection.execSQL(<span>Connection.java:2917</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.Statement.executeQuery(<span>Statement.java:824</span>)</p>
<p style="padding-left:60px;"><span> </span>at JDBCTest.main(<span>JDBCTest.java:26</span>)</p>
<p> </p>
<p><strong>Using mysql-connector-java-5.1.6-bin.jar and the same JDK 5 with 32MB heap:</strong></p>
<p style="padding-left:60px;">ET-COMMONS INFO: JVM MEMORY MONITOR =&gt; Total: 33  Used: 1  Free: 32</p>
<p style="padding-left:60px;">Retrieving data &#8230;</p>
<p style="padding-left:60px;">Ran out of memory at row: 0</p>
<p style="padding-left:60px;">java.lang.OutOfMemoryError: Java heap space</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.ByteArrayBuffer.getBytes(<span>ByteArrayBuffer.java:128</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.ByteArrayBuffer.readLenByteArray(<span>ByteArrayBuffer.java:248</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.nextRow(<span>MysqlIO.java:1304</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.readSingleRowSet(<span>MysqlIO.java:2272</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.getResultSet(<span>MysqlIO.java:423</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(<span>MysqlIO.java:1962</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.readAllResults(<span>MysqlIO.java:1385</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.MysqlIO.sqlQueryDirect(<span>MysqlIO.java:1728</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.Connection.execSQL(<span>Connection.java:2988</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.Connection.execSQL(<span>Connection.java:2917</span>)</p>
<p style="padding-left:60px;"><span> </span>at com.mysql.jdbc.Statement.executeQuery(<span>Statement.java:824</span>)</p>
<p style="padding-left:60px;"><span> </span>at JDBCTest.main(<span>JDBCTest.java:26</span>)</p>
<p> </p>
<p>Thus we see that both the old and new versions of the MySQL JDBC driver by default attempt to load the entire resultset into memory.</p>
<p> </p>
<p>I now increase the heap to 1GB to allow it to grow and find that the test query uses up &gt; 500MB of heap before it even starts the rs.next() loop.</p>
<p style="padding-left:60px;">ET-COMMONS INFO: JVM MEMORY MONITOR =&gt; Total: 33  Used: 1  Free: 32</p>
<p style="padding-left:60px;">Retrieving data &#8230;</p>
<p style="padding-left:60px;">ET-COMMONS INFO: JVM MEMORY MONITOR =&gt; Total: 298  Used: 183  Free: 115</p>
<p style="padding-left:60px;">ET-COMMONS INFO: JVM MEMORY MONITOR =&gt; Total: 527  Used: 381  Free: 146</p>
<p style="padding-left:60px;">Starting to retrieve data. Memory Used: 517</p>
<p style="padding-left:60px;">Done retrieving data =&gt; 2318284   Memory Used: 551</p>
<p> </p>
<p>Here is the code for this:</p>
<p> </p>
<p>            ResultSet rs = conn.createStatement().executeQuery(&#8220;&lt;sql query that returns lots of data&gt;&#8221;<span>);</span></p>
<p>            System.<span>out</span>.println(<span>&#8220;Starting to retrieve data. Memory Used: &#8220;</span> + getUsedMemory());</p>
<p>            <span>while</span> (rs.next()) {</p>
<p>                rs.getString(1);</p>
<p>                rowsReturned++;</p>
<p>            }</p>
<p>            System.<span>out</span>.println(<span>&#8220;Done retrieving data =&gt; &#8220;</span> + rowsReturned + <span>&#8221;   Memory Used: &#8220;</span>  </p>
<p>+ getUsedMemory());</p>
<p> </p>
<p>Thus you can see that the &#8220;executeQuery()&#8221; method loads up 500MB of data before it passes on the &#8220;rs.next()&#8221; loop. The full ResultSet is being buffered in memory.</p>
<p> </p>
<p><strong>Solution</strong></p>
<p>To make the JDBC driver stream the results instead of buffer them all first we do the following:</p>
<p>            stmt.setFetchSize(Integer.<span>MIN_VALUE</span>);</p>
<div>Then we get this result instead:</div>
<div>
<p style="padding-left:60px;">ET-COMMONS INFO: JVM MEMORY MONITOR =&gt; Total: 33  Used: 1  Free: 32</p>
<p style="padding-left:60px;">Retrieving data &#8230;</p>
<p style="padding-left:60px;">Starting to retrieve data. Memory Used: 2</p>
<p style="padding-left:60px;">ET-COMMONS INFO: JVM MEMORY MONITOR =&gt; Total: 33  Used: 1  Free: 32</p>
<p style="padding-left:60px;">ET-COMMONS INFO: JVM MEMORY MONITOR =&gt; Total: 33  Used: 2  Free: 31</p>
<p style="padding-left:60px;">Done retrieving data =&gt; 2318284   Memory Used: 2</p>
</div>
<p> </p>
<p>Now it behaves like we expect it to &#8230; only 2MB used instead of &gt; 500MB.</p>
<p> </p>
<p>There are some caveats:</p>
<ul>
<li>http://javaquirks.blogspot.com/2007/12/mysql-streaming-result-set.html</li>
<li>http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-implementation-notes.html</li>
</ul>
<div>In the second link of official documentation we read (emphasis in red added by myself):</div>
<div>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</div>
<div>
<p><span class="bold"><strong>ResultSet</strong></span></p>
<p><span style="color:#ff0000;">By default, ResultSets are completely retrieved and stored in memory.</span> In most cases this is the most efficient way to operate, and due to the design of the MySQL network protocol is easier to implement. <span style="color:#ff0000;">If you are working with ResultSets that have a large number of rows or large values, and can not allocate heap space in your JVM for the memory required, you can tell the driver to stream the results back one row at a time.</span></p>
<p>To enable this functionality, you need to create a Statement instance in the following manner:</p>
<pre>stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
              java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);</pre>
<p>The combination of a forward-only, read-only result set, with a fetch size of <code>Integer.MIN_VALUE</code> serves as a signal to the driver to stream result sets row-by-row. After this any result sets created with the statement will be retrieved row-by-row.</p>
<p>There are some caveats with this approach. You will have to read all of the rows in the result set (or close it) before you can issue any other queries on the connection, or an exception will be thrown.</p>
<p>The earliest the locks these statements hold can be released (whether they be <code>MyISAM</code> table-level locks or row-level locks in some other storage engine such as <code>InnoDB</code>) is when the statement completes.</p>
<p>If the statement is within scope of a transaction, then locks are released when the transaction completes (which implies that the statement needs to complete first). As with most other databases, statements are not complete until all the results pending on the statement are read or the active result set for the statement is closed.</p>
<p><span style="color:#ff0000;">Therefore, if using streaming results, you should process them as quickly as possible if you want to maintain concurrent access to the tables referenced by the statement producing the result set.</span></p>
</div>
<p> </p>
<p> </p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/benjchristensen.wordpress.com/59/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/benjchristensen.wordpress.com/59/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/59/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=59&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2008/05/27/mysql-jdbc-memory-usage-on-large-resultset/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>
	</item>
		<item>
		<title>Java Memory Usage &#8211; Ints</title>
		<link>http://benjchristensen.com/2008/05/27/java-memory-usage-ints/</link>
		<comments>http://benjchristensen.com/2008/05/27/java-memory-usage-ints/#comments</comments>
		<pubDate>Tue, 27 May 2008 07:41:01 +0000</pubDate>
		<dc:creator>Ben Christensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://benjchristensen.wordpress.com/?p=58</guid>
		<description><![CDATA[As I work on another set of indexes with large numbers of ints I&#8217;ve revisited how different storage mechanisms behave. I&#8217;ve set the JVM to just over 64MB (70MB to be precise). An int being 4 bytes means that 64MB of ints is as follows:        int sixtyFourMB = 64 * 1024 * [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=58&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As I work on another set of indexes with large numbers of ints I&#8217;ve revisited how different storage mechanisms behave.</p>
<p>I&#8217;ve set the JVM to just over 64MB (70MB to be precise).</p>
<p>An int being 4 bytes means that 64MB of ints is as follows:</p>
<p><span>       int</span> sixtyFourMB = 64 * 1024 * 1024 / 4;</p>
<p>That is 16,777,216 ints.</p>
<p>An int array can successfully store 64MB in the JVM meaning it is properly assigning each int to 4 bytes without overhead.</p>
<p>      int[] vals = new int[sixtyFourMB];</p>
<p>However, if you use ArrayList&lt;Integer&gt; you run out of memory after 3,392,918 ints being added.</p>
<p>That is 1/5 of what can be stored in the int[]!</p>
<p>Now, assigning the space to ArrayList is fine:</p>
<p>                ArrayList&lt;Integer&gt; ints = <span>new</span> ArrayList&lt;Integer&gt;(sixtyFourMB);</p>
<p>It&#8217;s when you add the Integer objects (int is cast to Integer behind the scenes in JDK 5) that it dies 1/5 in.</p>
<p>So the overhead is obviously in the Integer object.</p>
<p>I next try the Trove library and use the TIntArrayList.</p>
<p>If I leave it to assign its memory space by default, it runs out of memory at 10,485,760 (62%).</p>
<p>If however I tell it how many ints to expect it sizes itself properly and does not try to grow too large and fits the entire 64MB.</p>
<p>     TIntArrayList ints = <span>new</span> TIntArrayList(sixtyFourMB);</p>
<p>Thus, when backed by an int[] the memory can be efficiently stored, but when using an Object[] memory is very inefficient when attempting to store primitive ints.</p>
<p>Out of curiosity for what an Object() really does with memory I did the following:</p>
<p>            ArrayList&lt;Object&gt; ints = <span>new</span> ArrayList&lt;Object&gt;(sixtyFourMB);</p>
<p>            <span>for</span> (i = 0; i &lt; sixtyFourMB; i++) {</p>
<p>                ints.add(<span>null</span>);</p>
<p>            }</p>
<p>That works, it all fits in memory.</p>
<p>If however I change the &#8220;null&#8221; to &#8220;new Object()&#8221; such as:</p>
<p>                ints.add(<span>new</span> Object());</p>
<p>It fails at 702065 &#8230; which means that the object[] has already taken up the space and there is no room for the objects on the heap.</p>
<p>Thus, for storage of simple data primitive arrays is MUCH more efficient.</p>
<p>If the flexibility of the Collections API is needed for dynamic manipulation of those arrays then use <a href="http://trove4j.sourceforge.net/">GNU Trove</a> &#8230; but carefully or the dynamic sizing of the arrays in the background can cause a lot of waste.</p>
<p> </p>
<p>An old but interesting article specifies memory usage by normal objects and classes:</p>
<p>http://www.roseindia.net/javatutorials/determining_memory_usage_in_java.shtml</p>
<p>Here are two points from that article of note:</p>
<ol>
<li>The class takes up at least 8 bytes. So, if you say <code><strong><span style="color:#000080;">new</span></strong> Object();</code> you will allocate 8 bytes on the heap.</li>
<li>Each data member takes up 4 bytes, except for long and double which take up 8 bytes. Even if the data member is a byte, it will still take up 4 bytes! In addition, the amount of memory used is increased in 8 byte blocks. So, if you have a class that contains one byte it will take up 8 bytes for the class and 8 bytes for the data, totalling 16 bytes (groan!).</li>
</ol>
<div></div>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/benjchristensen.wordpress.com/58/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/benjchristensen.wordpress.com/58/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/benjchristensen.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/benjchristensen.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/benjchristensen.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/benjchristensen.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/benjchristensen.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/benjchristensen.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/benjchristensen.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/benjchristensen.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/benjchristensen.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/benjchristensen.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/benjchristensen.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/benjchristensen.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/benjchristensen.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/benjchristensen.wordpress.com/58/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=benjchristensen.com&#038;blog=859104&#038;post=58&#038;subd=benjchristensen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://benjchristensen.com/2008/05/27/java-memory-usage-ints/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/25a69d1e333ff36b77cf01b84b764182?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">benjchristensen</media:title>
		</media:content>
	</item>
	</channel>
</rss>
