-
-
Notifications
You must be signed in to change notification settings - Fork 819
Optimize parsing 19 digit longs #865
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
Changes from all commits
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 |
---|---|---|
|
@@ -152,6 +152,32 @@ public static long parseLong(char[] ch, int off, int len) | |
long val = parseInt(ch, off, len1) * L_BILLION; | ||
return val + (long) parseInt(ch, off+len1, 9); | ||
} | ||
|
||
/** | ||
* Parses an unsigned long made up of exactly 19 digits. | ||
* <p> | ||
* It is the callers responsibility to make sure the input is exactly 19 digits. | ||
* and fits into a 64bit long by calling {@link #inLongRange(char[], int, int, boolean)} | ||
* first. | ||
* <p> | ||
* Note that input String must NOT contain leading minus sign (even | ||
* if {@code negative} is set to true). | ||
* | ||
* @param ch Buffer that contains integer value to decode | ||
* @param off Offset of the first digit character in buffer | ||
* @param negative Whether original number had a minus sign | ||
* @return Decoded {@code long} value | ||
*/ | ||
public static long parseLong19(char[] ch, int off, boolean negative) | ||
{ | ||
// Note: caller must ensure length is [10, 18] | ||
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 you remove this comment line which doesn't match this code? |
||
long num = 0L; | ||
for (int i = 0; i < 19; i++) { | ||
char c = ch[off + i]; | ||
num = (num * 10) + (c - '0'); | ||
} | ||
return negative ? -num : num; | ||
cowtowncoder marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
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 you provide a jmh test project to prove this is faster? you can extend https://github.com/pjfanning/jackson-number-parse-bench if you like - you obviously have the test case, just would be handy to be able to run it independently 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. if this is really such a performance drag, shouldn't there be an openjdk issue - or something similar? 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.
Outsiders can't create OpenJDK issues. And even if, the discussions alone would probably take years. The time investment is massive with no guaranteed outcome. To give you a concrete example openjdk/jdk#6275. Even if everything would go smoothly we would still have to wait years until Jackson updates the minimum version to one that has the fixes. Jackson currently has a base of JDK 8 which was released 8 years ago. So we're looking at a best case of 10 years. 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.
I saw there is also https://github.com/FasterXML/jackson-benchmarks let me know what you prefer. 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. Whichever suits you. I have a vague recollection that jackson-benchmarks is configured to run the benchmarks for a long time. There was something about the project that made me go off and create my own where I could reconfigure the settings more readily. |
||
|
||
/** | ||
* Similar to {@link #parseInt(String)} but for {@code long} values. | ||
|
Uh oh!
There was an error while loading. Please reload this page.
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 looks wrong - the code seems to handle signed numbers
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 the same approach that
com.fasterxml.jackson.core.util.TextBuffer#contentsAsInt(boolean)
uses, it callscom.fasterxml.jackson.core.io.NumberInput#parseInt(char[], int, int)
that parses an optionally singed value unsigned by ignoring the sign and later flips the sign if it had a minus sign.