Re: RFR: 8276220: Reduce excessive allocations in DateTimeFormatter [v2]

2021-11-02 Thread Stephen Colebourne
On Mon, 1 Nov 2021 22:35:58 GMT, Claes Redestad  wrote:

>> The commentary on this line could probably be improved, but this is in a 
>> private printer-parser that will only be used for NANO_OF_SECOND and not any 
>> arbitrary `TemporalField` (see line 704), thus I fail to see how this 
>> assumption can fail (since NANO_OF_SECOND specifies a value range from 0 to 
>> 999,999,999).
>> 
>> I considered writing a more generic integral-fraction printer parser that 
>> would optimize for any value-range that fits in an int, but seeing how 
>> NANO_OF_SECOND is likely the only one used in practice and with a high 
>> demand for better efficiency I opted to specialize for it more directly.
>
> I see what you're saying that an arbitrary `Temporal` could define its own 
> fields with its own ranges, but I would consider it a design bug if such an 
> implementation at a whim redefines the value ranges of well-defined constants 
> such as `ChronoField.NANO_OF_SECOND` or `HOUR_OF_DAY`. I'd expect such a 
> `Temporal` would have to define its own enumeration of allowed 
> `TemporalField`s.

That isn't the design model however. The design model for the formatter is a 
`Map` like view of field to value. Any value may be associated with any field - 
that is exactly what `Temporal` offers. 
[`TempralAccessor.getLong()`](https://download.java.net/java/early_access/loom/docs/api/java.base/java/time/temporal/TemporalAccessor.html#getLong(java.time.temporal.TemporalField))
 is very explicit about this.

As indicated above, the positive part is that an hour-of-day of 26 can be 
printed by a user-written `WrappingLocalTime` class. The downside is the 
inability to make optimizing assumptions as per this code.

FWIW, I had originally intended to write dedicated private formatters where the 
pattern and type to be formatted are known, such as `LocalDate` and the ISO 
pattern.

-

PR: https://git.openjdk.java.net/jdk/pull/6188


Re: RFR: 8276220: Reduce excessive allocations in DateTimeFormatter [v2]

2021-11-01 Thread Claes Redestad
On Mon, 1 Nov 2021 22:27:08 GMT, Claes Redestad  wrote:

>> src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java 
>> line 3269:
>> 
>>> 3267: return false;
>>> 3268: }
>>> 3269: int val = value.intValue(); // NANO_OF_SECOND must fit in 
>>> an int and can't be negative
>> 
>> Unfortunately, this is not a valid assumption, and it affects the logic of 
>> the optimization more generally (methods where non-negative is assumed).
>> 
>> Basically, NANO_OF_SECOND (and all other fields in the formatter) can have 
>> any `long` value. Despite immediate appearances, the value is not limited to 
>> 0 to 999,999,999. This is because you are allowed to create an 
>> implementation of `Temporal` that returns values outside that range. No such 
>> class exists in the JDK, but such a class would be perfectly legal. As a 
>> related example, it would be perfectly value to write a time class that ran 
>> from 03:00 to 26:59 each day, thus HOUROF_DAY cannot be assumed by the 
>> formatter to be between 0 and 23.
>
> The commentary on this line could probably be improved, but this is in a 
> private printer-parser that will only be used for NANO_OF_SECOND and not any 
> arbitrary `TemporalField` (see line 704), thus I fail to see how this 
> assumption can fail (since NANO_OF_SECOND specifies a value range from 0 to 
> 999,999,999).
> 
> I considered writing a more generic integral-fraction printer parser that 
> would optimize for any value-range that fits in an int, but seeing how 
> NANO_OF_SECOND is likely the only one used in practice and with a high demand 
> for better efficiency I opted to specialize for it more directly.

I see what you're saying that an arbitrary `Temporal` could define its own 
fields with its own ranges, but I would consider it a design bug if such an 
implementation at a whim redefines the value ranges of well-defined constants 
such as `ChronoField.NANO_OF_SECOND` or `HOUR_OF_DAY`. I'd expect such a 
`Temporal` would have to define its own enumeration of allowed `TemporalField`s.

-

PR: https://git.openjdk.java.net/jdk/pull/6188


Re: RFR: 8276220: Reduce excessive allocations in DateTimeFormatter [v2]

2021-11-01 Thread Claes Redestad
> Prompted by a request from Volkan Yazıcı I took a look at why the java.time 
> formatters are less efficient for some common patterns than custom formatters 
> in apache-commons and log4j. This patch reduces the gap, without having 
> looked at the third party implementations. 
> 
> When printing times:
> - Avoid turning integral values into `String`s before appending them to the 
> buffer 
> - Specialize `appendFraction` for `NANO_OF_SECOND` to avoid use of 
> `BigDecimal`
> 
> This means a speed-up and reduction in allocations when formatting almost any 
> date or time pattern, and especially so when including sub-second parts 
> (`S-S`).
> 
> Much of the remaining overhead can be traced to the need to create a 
> `DateTimePrintContext` and adjusting `Instant`s into a `ZonedDateTime` 
> internally. We could likely also win performance by specializing some common 
> patterns.
> 
> Testing: tier1-3

Claes Redestad has updated the pull request incrementally with one additional 
commit since the last revision:

  Remove stray method

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/6188/files
  - new: https://git.openjdk.java.net/jdk/pull/6188/files/9e97b4dc..ee13139a

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=6188=01
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=6188=00-01

  Stats: 10 lines in 1 file changed: 0 ins; 10 del; 0 mod
  Patch: https://git.openjdk.java.net/jdk/pull/6188.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/6188/head:pull/6188

PR: https://git.openjdk.java.net/jdk/pull/6188