Java Code Optimization

1 minute read

Java Performance Optimization Techniques

1. Efficient Data Structures

Choosing the right data structures can significantly impact performance.

Using ArrayList for random access instead of LinkedList.

List<String> list = new ArrayList<>();
// Instead of
// List<String> list = new LinkedList<>();

2. Minimizing Object Creation

Excessive object creation can lead to high memory usage and increased garbage collection overhead.

Example: Use StringBuilder for string concatenation in loops instead of creating new String objects.

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

3. Using Primitives Instead of Wrappers

Primitives are faster and use less memory compared to their wrapper classes.

Example: Use int instead of Integer where possible.

int sum = 0;
for (int i = 0; i < 1000; i++) {
    sum += i;
}

4. Avoiding Synchronization Overhead

Use synchronization only when necessary, as it can introduce significant overhead.

Example: Use ConcurrentHashMap instead of Hashtable or synchronized HashMap.

Map<String, String> map = new ConcurrentHashMap<>();
// Instead of
// Map<String, String> map = Collections.synchronizedMap(new HashMap<>());

5. Optimizing Loops

Unnecessary operations inside loops can degrade performance.

Example: Cache the size of a list in a variable instead of calling the size() method repeatedly.

for (int i = 0, size = list.size(); i < size; i++) {
    // Perform operations
}

6. Efficient I/O Operations

Buffered I/O can significantly improve performance for reading and writing data.

Example: Use BufferedReader and BufferedWriter for I/O operations.

try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        // Process the line
    }
}
  1. Reducing Method Calls Avoid method calls in tight loops, especially if the method is small and called frequently.

Example: Inline small methods where possible.

  1. Using Caching Caching results of expensive operations can improve performance.

Example: Use ConcurrentHashMap for caching computed values.

Map<String, String> cache = new ConcurrentHashMap<>();
String result = cache.computeIfAbsent(key, k -> computeExpensiveValue(k));