Posts

StringBuffer is Dead, Long Live StringBuffer

When Java 5.0 was released on 30 th September 2004, it introduced StringBuilder as a replacement for StringBuffer in cases where thread safety isn't required. The idea was simple: if you're manipulating strings within a single thread, StringBuilder offers a faster, unsynchronized alternative to StringBuffer . This is an updated article from 2011 From the Javadoc for StringBuilder : This class provides an API compatible with StringBuffer , but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations. Is StringBuffer Really Dead? You might think that StringBuffer has become redundant, given that most single-threaded scenarios can use StringBuilder , and thread safety often require

What can make Java code go faster, and then slower?

It's well-known that the JVM optimises code during execution, resulting in faster performance over time. However, less commonly understood is how operations performed before a code section can negatively impact its execution speed. In this post, I'll use practical examples to explore how warming up and cooling down code affects performance. The code is available here for you to run Warming Up Code When code is executed repeatedly, the JVM optimises performance. Consider the following code snippet: int[] display = {0, 1, 10, 100, 1_000, 10_000, 20_000, 100_001}; for (int i = 0; i <= display[display.length - 1]; i++) { long start = System.nanoTime(); doTask(); long time = System.nanoTime() - start; if (Arrays.binarySearch(display, i) >= 0) System.out.printf("%,d: Took %,d us to serialise/deserialise GregorianCalendar%n", i, time / 1_000); } This code measures the time taken to execute doTask() over multiple iterations, printing

Overly Long Class Names in Java or Geeky Poem?

In Java development, clear and concise naming conventions are essential for code readability and maintainability. However, sometimes, we stumble upon class names that stretch the limits of practicality. One such example is InternalFrameTitlePaneMaximizeButtonWindowNotFocusedState . But did you know that in Java 6, this class name was even longer? Within the Java 6 JRE, there's a class with an astonishingly lengthy name: com.sun.java.swing.plaf.nimbus.InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState This mouthful appears to be the product of a code generator that needed to be reviewed, leading to redundant and cumbersome naming. Or is it a geeky poem buried in the code? InternalFrame InternalFrame Title Pane, Internal Frame Title Pane. Maximize Button Window, Not Focused State. The moral of the story is always check the readability/sanity of generated code. In this Hacker News Discussion another class was also consid

Unexpected Full GCs Triggered by RMI in Latency-Sensitive Applications

We observed an unexpected increase in Full Garbage Collections (Full GCs) while optimising a latency-sensitive application with minimal object creation. Despite reducing the frequency of minor GCs to enhance performance, the system began to exhibit hourly periodic pauses due to Full GCs, which was counterintuitive. Investigating the Source of Full GCs Upon closer examination, we discovered that the Java Remote Method Invocation (RMI) system was initiating Full GCs every hour. Specifically, the RMI Distributed Garbage Collector (DGC) checks if a GC has occurred in the last hour and, if not, forces a Full GC. This behaviour occurs even if the application does not actively use RMI, leading to unnecessary performance overhead. Understanding RMI's Impact on Garbage Collection The RMI DGC collects periodic garbage to clean up unused remote objects. By default, it is configured to trigger a Full GC if none has occurred within a specified interval (defaulting to one hour). This me

How SLOW can you read/write files in Java?

A common question on Stack Overflow is: Why is reading/writing from a file in Java so slow? What is the fastest way? The discussion often revolves around comparing NIO versus IO . However, the bottleneck is usually not the read/write operations themselves, and the specific approach often has little significance in the bigger picture. To demonstrate, I’ll show one of the simplest (and perhaps slowest) ways to read/write text, using PrintWriter and Files.lines(Path) . The code is available here While it’s slower than writing binary using NIO or IO , it’s fast enough for most typical use cases. Example Output The program on a Ryzen 5950X running Linux outputs: Run 1, Write speed: 0.900 GB/sec, read speed 0.832 GB/sec Run 2, Write speed: 0.918 GB/sec, read speed 1.208 GB/sec Run 3, Write speed: 0.933 GB/sec, read speed 1.197 GB/sec If you find that 900 MB/s is more than fast enough for your application, the specific method of reading/wri

Advanced Applications of Dynamic Code in Java

Dynamic code compilation and execution in Java offer powerful capabilities that can enhance application flexibility and performance. Back in 2008, I developed a library called Essence JCF , which has since evolved into the Java Runtime Compiler . Initially, its purpose was to load configuration files written in Java instead of traditional XML or properties files. A key advantage of this library is its ability to load classes into the current class loader, allowing immediate use of interfaces or classes without the need for reflection or additional class loaders. Why Use Dynamic Code Compilation? While dynamic code compilation didn't initially solve a pressing problem, over time, several practical use cases have emerged where it proves particularly beneficial: 1. Objects in Direct Memory By generating code dynamically, you can build data stores from interfaces that are either row-based or column-based, stored in the heap or direct memory. This approach reduces the number

Two Overlooked Uses of Enums in Java

Enums in Java are commonly used to represent a fixed set of constants. However, they offer more versatility than often realized. In this article, we'll explore two practical yet often overlooked uses of enums: creating utility classes and implementing singletons. 1. Using Enums as Utility Classes Utility classes contain static methods and are not meant to be instantiated. A typical approach is to define a class with a private constructor to prevent instantiation. Enums provide a more straightforward way to achieve this by leveraging their inherent characteristics. Here's how you can define a utility class using an enum: public enum MyUtils { ; public static String process(String text) { // Your utility method implementation return text.trim().toLowerCase(); } } By declaring an enum with no instances (note the semicolon after the enum name), you prevent instantiation naturally. This approach simplifies the code and clearly indicates tha