Skip to main content

Performance

Performance — performance optimization, benchmarking, and profiling in Java applications

Java Streams API Deep Dive + Collectors Cookbook

A practical cookbook for the Java Stream API and Collectors utility — filter/map/reduce essentials, groupingBy and partitioningBy patterns, performance gotchas, and AI prompts to refactor legacy loops into clean pipelines.

Performance Testing Using JUnit 6 (Benchmarks & Techniques)

A complete guide to performance testing in JUnit 6. Covers @Timeout for time bounds, assertTimeout for inline benchmarks, JMH (Java Microbenchmark Harness) setup with @Benchmark, Blackhole usage, integrating JMH results as JUnit assertions, and benchmarking Spring Boot methods.

Mutation Testing with PIT and JUnit 6 (Improve Test Quality)

A complete guide to mutation testing with PIT (Pitest) and JUnit 6. Covers what mutation testing is, Maven and Gradle setup, reading mutation reports, surviving mutant analysis, and how to use PIT to measure true test suite quality beyond code coverage.

Why Your JUnit Tests Are Slow (Performance Optimization Guide)

A performance optimization guide for slow JUnit 6 test suites. Covers measuring bottlenecks, Spring context duplication, using wrong test type, Testcontainers restarts, sequential execution, and provides a summary table with typical time savings per optimization.

Parallel Test Execution in JUnit 6: Configuration and Pitfalls

A complete guide to JUnit 6 parallel test execution: enabling and configuring parallelism, class vs method level concurrency, @Execution and @ResourceLock annotations, thread pool strategies, pitfall table with fixes, and real performance benchmarks.

Hibernate 7 Aggregate Functions: COUNT, SUM, AVG, GROUP BY/HAVING, and the Null-vs-Zero Trap

Pulling thousands of rows into Java just to sum or average them is the memory-first trap. This guide covers Hibernate 7's COUNT, SUM, AVG, MIN, MAX, GROUP BY/HAVING with typed record projections, the Criteria API equivalent, and HQL window functions, including the null-vs-zero trap on empty result sets and the correction that window functions have existed since Hibernate 6.2, not 7.

Pagination in Hibernate 7: LIMIT/OFFSET, the JOIN FETCH Trap, and Keyset Pagination

Fetching every row just to show ten is a linear-cost mistake. This guide covers Hibernate 7 pagination with setFirstResult/setMaxResults, ScrollableResults for batch jobs, keyset pagination, and the total-count pattern, plus the corrected JOIN FETCH in-memory-fallback trap: it only triggers when ordering by the fetched collection's own column, and the real warning code is HHH90003004, not HHH000104.

Hibernate 7 Batch Insert: 1M Rows in 12s — Settings, Benchmarks, and the JDBC Trap

One million rows, PostgreSQL, HikariCP pool of 10, SEQUENCE generator: approximately 12 seconds with proper Hibernate batch configuration. Without it, the same job runs for over two minutes — and that's before accounting for the OutOfMemoryError you get around row 80,000 if you skip the flush/clear cycle. The configuration is four properties. The JDBC trap is one silent gotcha that disables batching without any error. The flush/clear cadence is one loop pattern. This post covers all three and the approximate numbers so you can reason about what your specific job should take. The Problem: The "Chatty" Database Trap When you persist objects in a standard loop, Hibernate sends one INSERT or UPDATE statement per object. This creates massive network latency. Imagine you have 10,000 records and a 5ms network round-trip delay. You have already lost 50 seconds just to "talk" to the database, even before the engine starts processing the data. This is often called the "N+1 Problem of Writing." Each individual insert requires the database to parse the SQL, execute it, update indexes, and send an acknowledgment. Multiplying this overhead by thousands of records is the fastest way to kill application performance.