<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Performance Lab]]></title><description><![CDATA[Performance Lab]]></description><link>https://blog.perf-lab.io</link><generator>RSS for Node</generator><lastBuildDate>Sat, 25 Apr 2026 16:23:47 GMT</lastBuildDate><atom:link href="https://blog.perf-lab.io/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Introducing Performance Lab]]></title><description><![CDATA[Performance Lab is a new initiative dedicated to exploring the multifaceted world of software performance. Launched just a few weeks ago, our project delves deep into various performance domains, including system design, benchmarking, profiling, opti...]]></description><link>https://blog.perf-lab.io/introducing-performance-lab</link><guid isPermaLink="true">https://blog.perf-lab.io/introducing-performance-lab</guid><category><![CDATA[jmh]]></category><category><![CDATA[aloritim]]></category><category><![CDATA[Java]]></category><category><![CDATA[performance]]></category><category><![CDATA[Performance Optimization]]></category><dc:creator><![CDATA[M Z]]></dc:creator><pubDate>Sat, 05 Apr 2025 05:04:27 GMT</pubDate><content:encoded><![CDATA[<p>Performance Lab is a new initiative dedicated to exploring the multifaceted world of software performance. Launched just a few weeks ago, our project delves deep into various performance domains, including system design, benchmarking, profiling, optimization techniques, and much more. Each of these areas represents its own rich discipline worthy of focused exploration.</p>
<h2 id="heading-about-me">About Me</h2>
<p>I'm MZ, a technology veteran with experience dating back to the dot-com bubble era. My passion for software optimization began during my early career developing ISAPI filters and Apache modules designed to intercept server requests. These components demanded exceptional efficiency and reliability, as any bugs could potentially bring down entire servers.</p>
<p>Throughout my career, I've focused on building highly efficient software that maximizes hardware capabilities while reducing costs. My experience spans analytics projects aimed at identifying system bottlenecks and designing comprehensive end-to-end solutions for data processing, storage, and reporting systems.</p>
<h2 id="heading-performance-lab-our-journey-to-efficiency">Performance Lab: Our Journey to Efficiency</h2>
<p>Our journey begins from the bottom up. When a new programmer starts developing, whether it's an app or a service, they're working on code that needs to be as efficient as possible while still delivering the expected outcomes.</p>
<h2 id="heading-a-simple-example-sumab">A Simple Example: sum(a,b)</h2>
<p>Consider a basic example: creating functionality that calculates the sum of integers from 1 to n. When writing a code block for this functionality, there's a natural progression to efficiency:</p>
<ol>
<li><p><strong>Logic and flow of the block</strong> - Getting the core logic right</p>
</li>
<li><p><strong>Efficient algorithms</strong> - Finding optimal solutions</p>
</li>
<li><p><strong>Correct data structures</strong> - Choosing appropriate ways to store and access data</p>
</li>
<li><p><strong>Code-level optimization</strong> - Fine-tuning implementation details</p>
</li>
</ol>
<p>A decade ago, I took an algorithm course on Coursera.</p>
<p>I once took an algorithms course instructed by <a target="_blank" href="https://www.coursera.org/instructor/~246867">Kevin Wayne</a> and <a target="_blank" href="https://www.coursera.org/instructor/~250165">Robert Sedgewick</a> one phrase from Robert constantly echoed me “Can we do it better?“ This question challenges us to continuously improve our solutions. I recommend the great book <a target="_blank" href="https://amzn.to/4kS6oqQ">Algorithms (4th Edition)</a> witch inspired to think this way.</p>
<p>But this raises an important question: how do we measure and prove that our implementation is truly efficient? In the Java world, the answer is JMH (Java Microbenchmark Harness), which will be the topic of our next articles.</p>
<p>Thanks for joining us on this journey to performance excellence!</p>
<h2 id="heading-play-with-jmh">Play With JMH</h2>
<p>In the example above, we will use Maven.</p>
<p>Create a project if you do not have</p>
<pre><code class="lang-xml"> <span class="hljs-tag">&lt;<span class="hljs-name">properties</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">java.version</span>&gt;</span>17<span class="hljs-tag">&lt;/<span class="hljs-name">java.version</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">maven.compiler.source</span>&gt;</span>${java.version}<span class="hljs-tag">&lt;/<span class="hljs-name">maven.compiler.source</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">maven.compiler.target</span>&gt;</span>${java.version}<span class="hljs-tag">&lt;/<span class="hljs-name">maven.compiler.target</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">jmh.version</span>&gt;</span>1.37<span class="hljs-tag">&lt;/<span class="hljs-name">jmh.version</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">properties</span>&gt;</span>
</code></pre>
<p>Add JMH dependencies</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.openjdk.jmh<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>jmh-core<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${jmh.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.openjdk.jmh<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>jmh-generator-annprocess<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${jmh.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<p>Adding a benchmark runner for an easy run from IDE</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> io.performancelab;

<span class="hljs-keyword">import</span> org.openjdk.jmh.annotations.*;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BenchmarkRunner</span> </span>{
    <span class="hljs-comment">// easy run from IDE</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{
        org.openjdk.jmh.Main.main(args);
    }
}
</code></pre>
<p>Adding benchmarks class</p>
<pre><code class="lang-java"><span class="hljs-meta">@BenchmarkMode(Mode.Throughput)</span>
<span class="hljs-meta">@Fork(1)</span>
<span class="hljs-meta">@Threads(1)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PlayWithJMH</span> </span>{

    <span class="hljs-meta">@Benchmark</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sum_range</span><span class="hljs-params">(Blackhole blackhole)</span> </span>{
        <span class="hljs-keyword">int</span> x = Sum.sum_range(<span class="hljs-number">1</span>, <span class="hljs-number">1000</span>);
        blackhole.consume(x);
    }

    <span class="hljs-meta">@Benchmark</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sum_stream</span><span class="hljs-params">(Blackhole blackhole)</span> </span>{
        <span class="hljs-keyword">int</span> x = Sum.sum_stream(<span class="hljs-number">1</span>, <span class="hljs-number">1000</span>);
        blackhole.consume(x);
    }

    <span class="hljs-meta">@Benchmark</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sum_algo</span><span class="hljs-params">(Blackhole blackhole)</span> </span>{
        <span class="hljs-keyword">int</span> x = Sum.sum_algo(<span class="hljs-number">1</span>, <span class="hljs-number">1000</span>);
        blackhole.consume(x);
    }

}
</code></pre>
<p>Adding @BenchmarkMode to define the benchmarking metrics. There are different types of Benchmarking. In this example, we are using Throughput. By adding @Benchmark, JMH will benchmark the method individually. There are a few other modes we will expand in the next article.</p>
<p>The current example is simple, but it can show the strategy for optimization</p>
<p>You start with some method or flow that you want to optimize</p>
<p>you have the current implementation, which is a naive one</p>
<p>Some of the developers take the stream approach (more elegant - but does it have good performance)</p>
<p>Others take high school simple algorithm</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Sum</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">sum_range</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span> </span>{
        <span class="hljs-keyword">int</span> tmp = <span class="hljs-number">0</span>;
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = a; i &lt;= b; i++) {
            tmp += i;
        }
        <span class="hljs-keyword">return</span> tmp;
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">sum_stream</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span> </span>{
        IntStream intStream = IntStream.range(a, b);
        <span class="hljs-keyword">return</span> intStream.reduce(<span class="hljs-number">0</span>, Integer::sum);
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">sum_algo</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span> </span>{
        <span class="hljs-keyword">int</span> n = b - a + <span class="hljs-number">1</span>;
        <span class="hljs-keyword">return</span> (n * (a + b)) / <span class="hljs-number">2</span>;
    }
}
</code></pre>
<p>To run the benchmark not from the IDE lets add to pom.xml file</p>
<pre><code class="lang-xml">    <span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.maven.plugins<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>maven-compiler-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.13.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">source</span>&gt;</span>17<span class="hljs-tag">&lt;/<span class="hljs-name">source</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">target</span>&gt;</span>17<span class="hljs-tag">&lt;/<span class="hljs-name">target</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">annotationProcessorPaths</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">path</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.openjdk.jmh<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>jmh-generator-annprocess<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.37<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">path</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">annotationProcessorPaths</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.maven.plugins<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>maven-shade-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.4.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">executions</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">execution</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">phase</span>&gt;</span>package<span class="hljs-tag">&lt;/<span class="hljs-name">phase</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">goals</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">goal</span>&gt;</span>shade<span class="hljs-tag">&lt;/<span class="hljs-name">goal</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">goals</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">transformers</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">transformer</span> <span class="hljs-attr">implementation</span>=<span class="hljs-string">"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">manifestEntries</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">Main-Class</span>&gt;</span>org.openjdk.jmh.Main<span class="hljs-tag">&lt;/<span class="hljs-name">Main-Class</span>&gt;</span>
                  <span class="hljs-tag">&lt;/<span class="hljs-name">manifestEntries</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">transformer</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">transformers</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">execution</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">executions</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span>
</code></pre>
<p>Run maven (to create the package)</p>
<pre><code class="lang-bash">mvn clean install package
</code></pre>
<p>Run jar file</p>
<pre><code class="lang-bash">java -jar target/play-with-jmh-1.0-SNAPSHOT.jar
</code></pre>
<p>Results</p>
<p>Let’s explore the results</p>
<pre><code class="lang-plaintext">Benchmark                           Mode  Cnt           Score          Error  Units
PlayWithJMH.sum_algo               thrpt    5  1771912740.903 ± 76827725.410  ops/s
PlayWithJMH.sum_range              thrpt    5     3243665.358 ±    54706.748  ops/s
PlayWithJMH.sum_stream             thrpt    5     2983338.638 ±   169515.222  ops/s
</code></pre>
<p>Looking at the results, we defined the BenchmarkMode as Throughput.</p>
<p>Throughput is counting the number of invocations we did in each method (Bigger is better)</p>
<p>sum_stream creates a stream of integers in the defined range and reduces them with the sum, a kind of new API in Java, but less preferred than the naive approach, which is to have a for loop that accumulates the values. The sum_algo method wins by far from the other methods. If you can switch to a more optimal algorithm, this will be the biggest improvement that you can achieve.</p>
<p>You can find the complete running benchmark on GitH<a target="_blank" href="https://github.com/mzperflab/play-with-jmh">ub</a>.</p>
<p>See you in the following article when we dive deep into JMH.</p>
]]></content:encoded></item></channel></rss>