-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8345668: ZoneOffset.ofTotalSeconds performance regression #22854
Changes from all commits
3df7e9f
1e09b8b
8dca103
9553ebd
4dac7ba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. | ||
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
|
@@ -424,11 +424,17 @@ public static ZoneOffset ofTotalSeconds(int totalSeconds) { | |
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00"); | ||
} | ||
if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) { | ||
return SECONDS_CACHE.computeIfAbsent(totalSeconds, totalSecs -> { | ||
ZoneOffset result = new ZoneOffset(totalSecs); | ||
Integer totalSecs = totalSeconds; | ||
ZoneOffset result = SECONDS_CACHE.get(totalSecs); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, each call may allocate an Integer object. The maximum number of ZoneOffsets that need to be cached here is only 148. Using AtomicReferenceArray is better than AtomicConcurrentHashMap. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For example: static final AtomicReferenceArray<ZoneOffset> MINUTES_15_CACHE = new AtomicReferenceArray<>(37 * 4);
public static ZoneOffset ofTotalSeconds(int totalSeconds) {
// ...
int minutes15Rem = totalSeconds / (15 * SECONDS_PER_MINUTE);
if (totalSeconds - minutes15Rem * 15 * SECONDS_PER_MINUTE == 0) {
int cacheIndex = minutes15Rem + 18 * 4;
ZoneOffset result = MINUTES_15_CACHE.get(cacheIndex);
if (result == null) {
result = new ZoneOffset(totalSeconds);
if (!MINUTES_15_CACHE.compareAndSet(cacheIndex, null, result)) {
result = MINUTES_15_CACHE.get(minutes15Rem);
}
}
return result;
}
// ...
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi Shaojin, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can I submit a PR to make this improvement? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @wenshao I agree with your proposal. Also for this part: ZoneOffset result = MINUTES_15_CACHE.get(cacheIndex);
if (result == null) {
result = new ZoneOffset(totalSeconds);
if (!MINUTES_15_CACHE.compareAndSet(cacheIndex, null, result)) {
result = MINUTES_15_CACHE.get(minutes15Rem);
}
} I recommend a rewrite: ZoneOffset result = MINUTES_15_CACHE.getPlain(cacheIndex);
if (result == null) {
result = new ZoneOffset(totalSeconds);
ZoneOffset existing = MINUTES_15_CACHE.compareAndExchange(cacheIndex, null, result);
return existing == null ? result : existing;
} The |
||
if (result == null) { | ||
result = new ZoneOffset(totalSeconds); | ||
var existing = SECONDS_CACHE.putIfAbsent(totalSecs, result); | ||
if (existing != null) { | ||
result = existing; | ||
} | ||
ID_CACHE.putIfAbsent(result.getId(), result); | ||
return result; | ||
}); | ||
} | ||
return result; | ||
} else { | ||
return new ZoneOffset(totalSeconds); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't be 2025 too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR was published last year and
ZoneOffset
has not changed since then. So I think 2024 is fine