<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    Hi,<br>
    <br>
    Leap year computation is well trodden ground. You might find <a href="https://www.benjoffe.com/fast-leap-year">Ben Joffe's</a>
    article interesting among others.<br>
    <br>
    There is also an amazing amount of optimization that occurs after
    the code is written and<br>
    the compilation to different instruction sets is taken into account.<br>
    <br>
    Some hardware techniques that come into play are:<br>
     - Branch prediction, in which the cpu pre-fetches both instruction
    paths and in some cases speculatively executes down both paths,
    making a late choice to pick the proper result.<br>
     - Conditional assignments in which there is no branch, just a
    register load that is conditional on some previous condition.<br>
     - etc...<br>
    <br>
    I'd expect to see different performance results on different
    architectures. (x64, aarch64, etc).<br>
    Sometimes, its hard to pick which variant to leave in the source
    code.<br>
    Frequently, a good compromise is to make sure the algorithm is
    correct and easy to understand and let the optimizer do its best.<br>
    <br>
    Regards, Roger<br>
    <br>
    <div class="moz-cite-prefix">On 12/15/25 2:55 PM, Raffaello
      Giulietti wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CH0PR10MB525786FED73808B2D28E4F5B87ADA@CH0PR10MB5257.namprd10.prod.outlook.com">
      <pre wrap="" class="moz-quote-pre">BTW, the variant below excluded 75% of the non-leap years with just one comparison:
```
return (year & 0x3) == 0 && ((year & 0xF) == 0 || year % 100 != 0)
```


________________________________________
From: Memory <a class="moz-txt-link-rfc2396E" href="mailto:smqy2314@gmail.com"><smqy2314@gmail.com></a>
Sent: Sunday, December 14, 2025 18:23
To: Raffaello Giulietti
Cc: <a class="moz-txt-link-abbreviated" href="mailto:core-libs-dev@openjdk.org">core-libs-dev@openjdk.org</a>
Subject: [External] : Re: Question about potential optimization for Year.isLeap()

Hi,

Thanks for the correction. I confused the implementations.

I'm proposing to change:

```java
return (year & 15) == 0 ? (year & 3) == 0 : (year & 3) == 0 && year % 100 != 0;
```

to:

```java
return (year & 15) == 0 || ((year & 3) == 0 && year % 100 != 0);
```

At the low level, this should be slightly faster because:

1. Fewer CPU branches - Ternary creates a true branch, while logical operators use short-circuit evaluation
2. Better for branch prediction - Simpler control flow pattern
3. Less operation duplication - The current code conceptually checks (year & 3) == 0 twice in the false case

However, I understand any performance difference would likely be minimal. If the team prefers the current ternary operator for better readability, I fully respect that decision.

Raffaello Giulietti <<a class="moz-txt-link-abbreviated" href="mailto:raffaello.giulietti@oracle.com">raffaello.giulietti@oracle.com</a><a class="moz-txt-link-rfc2396E" href="mailto:raffaello.giulietti@oracle.com"><mailto:raffaello.giulietti@oracle.com></a>> 于 2025年12月14日周日 19:45写道:
Hi,

the current logic in mainline is
```
        return (year & 15) == 0 ? (year & 3) == 0 : (year & 3) == 0 && year % 100 != 0;
```
(see <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/blob/fb531cdaf3b30034e0efa86b9b20558478ce94d0/src/java.base/share/classes/java/time/Year.java#L321">https://github.com/openjdk/jdk/blob/fb531cdaf3b30034e0efa86b9b20558478ce94d0/src/java.base/share/classes/java/time/Year.java#L321</a><a class="moz-txt-link-rfc2396E" href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/fb531cdaf3b30034e0efa86b9b20558478ce94d0/src/java.base/share/classes/java/time/Year.java*L321__;Iw!!ACWV5N9M2RV99hQ!ILBGqbgmHKbXqqdQShgtaBhShlZKl8_Pe_pvHC1yFBjQp2pUZrgcTzDZP6efKRPT8iVsh9IrxVmyRfl8LtnSiu_w$"><https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/fb531cdaf3b30034e0efa86b9b20558478ce94d0/src/java.base/share/classes/java/time/Year.java*L321__;Iw!!ACWV5N9M2RV99hQ!ILBGqbgmHKbXqqdQShgtaBhShlZKl8_Pe_pvHC1yFBjQp2pUZrgcTzDZP6efKRPT8iVsh9IrxVmyRfl8LtnSiu_w$></a>)


________________________________________
From: core-libs-dev <<a class="moz-txt-link-abbreviated" href="mailto:core-libs-dev-retn@openjdk.org">core-libs-dev-retn@openjdk.org</a><a class="moz-txt-link-rfc2396E" href="mailto:core-libs-dev-retn@openjdk.org"><mailto:core-libs-dev-retn@openjdk.org></a>> on behalf of Memory <<a class="moz-txt-link-abbreviated" href="mailto:smqy2314@gmail.com">smqy2314@gmail.com</a><a class="moz-txt-link-rfc2396E" href="mailto:smqy2314@gmail.com"><mailto:smqy2314@gmail.com></a>>
Sent: Sunday, December 14, 2025 09:45
To: <a class="moz-txt-link-abbreviated" href="mailto:core-libs-dev@openjdk.org">core-libs-dev@openjdk.org</a><a class="moz-txt-link-rfc2396E" href="mailto:core-libs-dev@openjdk.org"><mailto:core-libs-dev@openjdk.org></a>
Subject: Question about potential optimization for Year.isLeap()

Hello core-libs-dev team,

My name is Memory2314, and I am a new contributor currently waiting for my Oracle Contributor Agreement (OCA) to be processed.

I have been studying the `java.time.Year.isLeap()` method and would like to propose a micro-optimization:

**Current logic:**
```java
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
```

**Proposed optimization:**
```java
return (year & 15) == 0 || ((year & 3) == 0 && year % 100 != 0);
```

**Key improvements:**
- Replaces `year % 4 == 0` with bitwise `(year & 3) == 0`
- Uses `(year & 15) == 0` to efficiently detect years divisible by 400
- Reduces modulo operations from 3 to 1 in the common case

**Verification benchmark:**
```java
public static void main(String[] args) {
    int[] years = new int[1_000_000_000];
    Random random = new Random();
    for (int i = 0; i < years.length; i++) {
        years[i] = 1970 + random.nextInt(5000 - 1970 + 1);
    }

    long start1 = System.currentTimeMillis();
    for (int year : years) {
        boolean result = isLeapOriginal(year);
    }
    System.out.println("Original: " + (System.currentTimeMillis()-start1) + "ms");

    long start2 = System.currentTimeMillis();
    for (int year : years) {
        boolean result = isLeapOptimized(year);
    }
    System.out.println("Optimized: " + (System.currentTimeMillis()-start2) + "ms");
}

public static boolean isLeapOriginal(long year) {
    return (year & 15) == 0 ? (year & 3) == 0 : (year & 3) == 0 && year % 100 != 0;
}

public static boolean isLeapOptimized(long year) {
    return (year & 15) == 0 || ((year & 3) == 0 && year % 100 != 0);
}
```

**Correctness verification:** I've tested this logic extensively, including edge cases like year 0, negative years (proleptic Gregorian), and all century boundaries from -10,000 to 10,000.

I am aware that I cannot submit a formal patch until my OCA is complete. However, I would be very grateful for your initial technical feedback on this approach before I proceed to create a fully tested patch with benchmarks.

Once my OCA is in place, would there be a maintainer or an experienced contributor interested in sponsoring this change if it proves worthwhile?

Thank you for your time and consideration.

Best regards,
Memory2314
</pre>
    </blockquote>
    <br>
  </body>
</html>