Skip to content

⚡️ Speed up method LongValue.equals by 9%#36

Open
codeflash-ai[bot] wants to merge 1 commit intomasterfrom
codeflash/optimize-LongValue.equals-ml8frixg
Open

⚡️ Speed up method LongValue.equals by 9%#36
codeflash-ai[bot] wants to merge 1 commit intomasterfrom
codeflash/optimize-LongValue.equals-ml8frixg

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Feb 4, 2026

📄 9% (0.09x) speedup for LongValue.equals in client/src/com/aerospike/client/Value.java

⏱️ Runtime : 10.0 microseconds 9.18 microseconds (best of 5 runs)

📝 Explanation and details

The optimized code achieves an 8% runtime improvement (from 10.0μs to 9.18μs) by applying three key optimizations to the equals() method:

Primary Optimization - Identity Check:
Added an early-exit identity check (if (this == other) return true;) that immediately returns true when comparing an object to itself. This is a common case in equality comparisons and avoids all subsequent checks, providing significant speedup when objects are compared to themselves (as demonstrated in the testSameInstance_ReturnsTrue test cases).

Secondary Optimizations:

  1. Reduced Method Calls: Replaced this.getClass().equals(other.getClass()) with the more direct other.getClass() != this.getClass(). The original version involves two virtual method calls (getClass() twice) plus a third call to equals() on the Class object. The optimized version only calls getClass() twice and uses reference equality (!=) which is a native operation, eliminating the virtual method call overhead.

  2. Single Cast Operation: Changed from casting on every access (((LongValue)other).value) to casting once and storing in a local variable (LongValue lv = (LongValue) other). This eliminates redundant type casting and improves readability without changing behavior.

Performance Impact:
These optimizations are particularly effective for:

  • Self-comparison scenarios where the same instance is compared (immediate return)
  • High-frequency equality checks as shown in the testRepeatedComparisons_Performance_NoFailure test (100,000 iterations)
  • Map/Set lookups where equals() is called frequently during hash collision resolution

The optimizations maintain identical correctness across all test cases including boundary conditions (Long.MAX_VALUE, Long.MIN_VALUE), null checks, type mismatches, and different value comparisons, while delivering measurable runtime improvements through reduced virtual method calls and early exits.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 40 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage No coverage data found for equals
🌀 Click to see Generated Regression Tests
package com.aerospike.client;

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class ValueTest {
    private Value defaultInstance;

    @Before
    public void setUp() {
        // Create a concrete Value instance using the library factory method.
        // Using a long to obtain the LongValue concrete implementation.
        defaultInstance = Value.get(0L);
    }

    @Test
    public void testSameValueDifferentInstances_ReturnsTrue() {
        Value a = Value.get(123L);
        Value b = Value.get(123L);
        assertTrue("Two LongValue instances with same long should be equal", a.equals(b));
    }

    @Test
    public void testSameInstance_ReturnsTrue() {
        Value a = Value.get(5L);
        assertTrue("Value should be equal to itself", a.equals(a));
    }

    @Test
    public void testDifferentValueSameType_ReturnsFalse() {
        Value a = Value.get(1L);
        Value b = Value.get(2L);
        assertFalse("Two LongValue instances with different longs should not be equal", a.equals(b));
    }

    @Test
    public void testNullComparison_ReturnsFalse() {
        Value a = Value.get(1L);
        assertFalse("Comparison with null should return false", a.equals(null));
    }

    @Test
    public void testDifferentClassSameNumericRepresentation_ReturnsFalse() {
        Value longVal = Value.get(100L);
        Value stringVal = Value.get("100");
        assertFalse("LongValue should not equal StringValue even if textual representation matches", longVal.equals(stringVal));
    }

    @Test
    public void testJavaLongObjectComparison_ReturnsFalse() {
        Value a = Value.get(42L);
        Long javaLong = Long.valueOf(42L);
        assertFalse("LongValue should not equal java.lang.Long", a.equals(javaLong));
    }

    @Test
    public void testIntVsLongSameNumeric_ReturnsFalse() {
        Value intVal = Value.get(123);   // expected to be IntegerValue
        Value longVal = Value.get(123L); // LongValue
        assertFalse("IntegerValue and LongValue with same numeric value should not be equal (different classes)", intVal.equals(longVal));
    }

    @Test
    public void testBoundary_MaxLong_EqualsTrue() {
        Value a = Value.get(Long.MAX_VALUE);
        Value b = Value.get(Long.MAX_VALUE);
        assertTrue("Long.MAX_VALUE should be equal between LongValue instances", a.equals(b));
    }

    @Test
    public void testBoundary_MinLong_EqualsTrue() {
        Value a = Value.get(Long.MIN_VALUE);
        Value b = Value.get(Long.MIN_VALUE);
        assertTrue("Long.MIN_VALUE should be equal between LongValue instances", a.equals(b));
    }

    @Test
    public void testRepeatedComparisons_Performance_NoFailure() {
        Value a = Value.get(9999L);
        Value b = Value.get(9999L);
        boolean result = true;
        // Perform a large number of comparisons to exercise equals repeatedly.
        // The loop count is moderate to avoid excessively long test runs while still exercising repeated calls.
        for (int i = 0; i < 100_000; i++) {
            if (!a.equals(b)) {
                result = false;
                break;
            }
        }
        assertTrue("Repeated equals comparisons should consistently return true for equal LongValue instances", result);
    }
}
package com.aerospike.client;

import org.junit.Test;
import org.junit.Before;
import static org.junit.Assert.*;
import com.aerospike.client.Value;

/**
 * Unit tests for Value.LongValue.equals(Object)
 */
public class ValueTest {
    private Value instance;

    @Before
    public void setUp() {
        // Use a concrete Value implementation (LongValue) as required.
        instance = new Value.LongValue(123L);
    }

    @Test
    public void testEquals_SameInstance_ReturnsTrue() {
        // Same instance should be equal to itself
        assertTrue(instance.equals(instance));
    }

    @Test
    public void testEquals_SameClassSameValue_ReturnsTrue() {
        // Two LongValue instances with same long should be equal
        Value other = new Value.LongValue(123L);
        assertTrue(instance.equals(other));
    }

    @Test
    public void testEquals_Symmetric_ReturnsTrue() {
        // Symmetry: if a.equals(b) then b.equals(a)
        Value a = new Value.LongValue(5000L);
        Value b = new Value.LongValue(5000L);
        assertTrue(a.equals(b));
        assertTrue(b.equals(a));
    }

    @Test
    public void testEquals_DifferentValue_ReturnsFalse() {
        // Same class but different stored long -> not equal
        Value other = new Value.LongValue(124L);
        assertFalse(instance.equals(other));
    }

    @Test
    public void testEquals_Null_ReturnsFalse() {
        // Comparing to null should return false
        assertFalse(instance.equals(null));
    }

    @Test
    public void testEquals_DifferentType_ReturnsFalse() {
        // Comparing to a different type (e.g., java.lang.Long) should return false
        Long longObj = Long.valueOf(123L);
        assertFalse(instance.equals(longObj));
    }

    @Test
    public void testEquals_BoundaryMaxValue_ReturnsTrue() {
        // Boundary condition: Long.MAX_VALUE equality
        Value max1 = new Value.LongValue(Long.MAX_VALUE);
        Value max2 = new Value.LongValue(Long.MAX_VALUE);
        assertTrue(max1.equals(max2));
    }

    @Test
    public void testEquals_BoundaryMinValue_ReturnsTrue() {
        // Boundary condition: Long.MIN_VALUE equality
        Value min1 = new Value.LongValue(Long.MIN_VALUE);
        Value min2 = new Value.LongValue(Long.MIN_VALUE);
        assertTrue(min1.equals(min2));
    }

    @Test
    public void testEquals_BoundaryMaxAndMin_NotEqual() {
        // Max and Min are different
        Value max = new Value.LongValue(Long.MAX_VALUE);
        Value min = new Value.LongValue(Long.MIN_VALUE);
        assertFalse(max.equals(min));
    }

    @Test
    public void testEquals_Performance_ManyComparisons_AllEqual() {
        // Large-scale repetitive equality checks to ensure consistent behavior/performance.
        // Keep iterations reasonable to avoid slowing test suite too much.
        final int iterations = 100_000;
        Value base = new Value.LongValue(9999L);
        boolean allEqual = true;

        for (int i = 0; i < iterations; i++) {
            Value v = new Value.LongValue(9999L);
            if (!base.equals(v)) {
                allEqual = false;
                break;
            }
        }
        assertTrue(allEqual);
    }
}

To edit these changes git checkout codeflash/optimize-LongValue.equals-ml8frixg and push.

Codeflash Static Badge

The optimized code achieves an **8% runtime improvement** (from 10.0μs to 9.18μs) by applying three key optimizations to the `equals()` method:

**Primary Optimization - Identity Check:**
Added an early-exit identity check (`if (this == other) return true;`) that immediately returns `true` when comparing an object to itself. This is a common case in equality comparisons and avoids all subsequent checks, providing significant speedup when objects are compared to themselves (as demonstrated in the `testSameInstance_ReturnsTrue` test cases).

**Secondary Optimizations:**

1. **Reduced Method Calls:** Replaced `this.getClass().equals(other.getClass())` with the more direct `other.getClass() != this.getClass()`. The original version involves two virtual method calls (`getClass()` twice) plus a third call to `equals()` on the Class object. The optimized version only calls `getClass()` twice and uses reference equality (`!=`) which is a native operation, eliminating the virtual method call overhead.

2. **Single Cast Operation:** Changed from casting on every access (`((LongValue)other).value`) to casting once and storing in a local variable (`LongValue lv = (LongValue) other`). This eliminates redundant type casting and improves readability without changing behavior.

**Performance Impact:**
These optimizations are particularly effective for:
- **Self-comparison scenarios** where the same instance is compared (immediate return)
- **High-frequency equality checks** as shown in the `testRepeatedComparisons_Performance_NoFailure` test (100,000 iterations)
- **Map/Set lookups** where `equals()` is called frequently during hash collision resolution

The optimizations maintain identical correctness across all test cases including boundary conditions (Long.MAX_VALUE, Long.MIN_VALUE), null checks, type mismatches, and different value comparisons, while delivering measurable runtime improvements through reduced virtual method calls and early exits.
@codeflash-ai codeflash-ai bot requested a review from HeshamHM28 February 4, 2026 19:44
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: Medium Optimization Quality according to Codeflash labels Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: Medium Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants