<!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>