[
https://issues.apache.org/jira/browse/LOG4J2-2399?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16577391#comment-16577391
]
ASF GitHub Bot commented on LOG4J2-2399:
----------------------------------------
Github user cakofony commented on the issue:
https://github.com/apache/logging-log4j2/pull/208
That is correct for this input, though it is entirely dependent on the cost
of converting parameters into string values.
A benchmark with eight string values rather than beans with allocation in
the tostring implementation is much closer, though both of the asynchronously
formatted benchmarks are identical, because the work on the application thread
is the same:
```
Benchmark
(asyncFormatting) (messageFactory) Mode
Cnt Score Error Units
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams
false ParameterizedMessageFactory sample
227620 2754.177 ± 411.508 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.00
false ParameterizedMessageFactory sample
2036.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.50
false ParameterizedMessageFactory sample
2252.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.90
false ParameterizedMessageFactory sample
2492.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.95
false ParameterizedMessageFactory sample
2832.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.99
false ParameterizedMessageFactory sample
5792.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.999
false ParameterizedMessageFactory sample 23968.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.9999
false ParameterizedMessageFactory sample 51095.994
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p1.00
false ParameterizedMessageFactory sample
16596992.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams
false ReusableMessageFactory sample
230147 2444.984 ± 15.601 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.00
false ReusableMessageFactory sample
1938.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.50
false ReusableMessageFactory sample
2264.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.90
false ReusableMessageFactory sample
2456.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.95
false ReusableMessageFactory sample
2580.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.99
false ReusableMessageFactory sample
5008.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.999
false ReusableMessageFactory sample 23328.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.9999
false ReusableMessageFactory sample 53684.634
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p1.00
false ReusableMessageFactory sample
702464.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams
true ParameterizedMessageFactory sample
247582 1183.063 ± 8.424 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.00
true ParameterizedMessageFactory sample
941.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.50
true ParameterizedMessageFactory sample
1036.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.90
true ParameterizedMessageFactory sample
1130.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.95
true ParameterizedMessageFactory sample
1212.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.99
true ParameterizedMessageFactory sample
3512.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.999
true ParameterizedMessageFactory sample 20941.344
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.9999
true ParameterizedMessageFactory sample 34140.813
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p1.00
true ParameterizedMessageFactory sample
108544.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams
true ReusableMessageFactory sample
195230 441.564 ± 8.628 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.00
true ReusableMessageFactory sample
270.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.50
true ReusableMessageFactory sample
366.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.90
true ReusableMessageFactory sample
432.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.95
true ReusableMessageFactory sample
492.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.99
true ReusableMessageFactory sample
1258.000 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.999
true ReusableMessageFactory sample 18848.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p0.9999
true ReusableMessageFactory sample 30772.650
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput8StringParams:throughput8StringParams·p1.00
true ReusableMessageFactory sample
242944.000 ns/op
```
A test with fewer parameters shows a much smaller difference:
Updated to `log("Hello {}", "World")`
```
Benchmark
(asyncFormatting) (messageFactory) Mode
Cnt Score Error Units
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam
false ParameterizedMessageFactory sample
313489 535.499 ± 7.370 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.00
false ParameterizedMessageFactory sample 368.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.50
false ParameterizedMessageFactory sample 454.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.90
false ParameterizedMessageFactory sample 520.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.95
false ParameterizedMessageFactory sample 596.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.99
false ParameterizedMessageFactory sample 1124.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.999
false ParameterizedMessageFactory sample 19104.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.9999
false ParameterizedMessageFactory sample 53600.640
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p1.00
false ParameterizedMessageFactory sample 130432.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam
false ReusableMessageFactory sample
323033 509.602 ± 10.065 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.00
false ReusableMessageFactory sample 290.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.50
false ReusableMessageFactory sample 426.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.90
false ReusableMessageFactory sample 575.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.95
false ReusableMessageFactory sample 630.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.99
false ReusableMessageFactory sample 1068.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.999
false ReusableMessageFactory sample 16800.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.9999
false ReusableMessageFactory sample 38904.077
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p1.00
false ReusableMessageFactory sample 619520.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam
true ParameterizedMessageFactory sample
192159 463.767 ± 8.593 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.00
true ParameterizedMessageFactory sample 255.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.50
true ParameterizedMessageFactory sample 386.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.90
true ParameterizedMessageFactory sample 452.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.95
true ParameterizedMessageFactory sample 516.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.99
true ParameterizedMessageFactory sample 1476.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.999
true ParameterizedMessageFactory sample 17109.760
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.9999
true ParameterizedMessageFactory sample 43423.232
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p1.00
true ParameterizedMessageFactory sample 131584.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam
true ReusableMessageFactory sample
221207 381.790 ± 5.879 ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.00
true ReusableMessageFactory sample 180.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.50
true ReusableMessageFactory sample 320.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.90
true ReusableMessageFactory sample 419.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.95
true ReusableMessageFactory sample 472.000
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.99
true ReusableMessageFactory sample 1119.840
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.999
true ReusableMessageFactory sample 14268.032
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p0.9999
true ReusableMessageFactory sample 29352.806
ns/op
BackgroundFormattingAsyncLoggersBenchmark.throughput1StringParam:throughput1StringParam·p1.00
true ReusableMessageFactory sample 123648.000
ns/op
```
Is the additional complexity worthwhile? I defer to your judgement @remkop.
> Reusable Messages do not respect log4j.format.msg.async
> -------------------------------------------------------
>
> Key: LOG4J2-2399
> URL: https://issues.apache.org/jira/browse/LOG4J2-2399
> Project: Log4j 2
> Issue Type: Task
> Components: Core
> Reporter: Carter Kozak
> Assignee: Carter Kozak
> Priority: Major
>
> Setting "log4j.format.msg.async" applies only to messages that do not
> implement ReusableMessage.
> On applications using asynchronous logging with message formatting in the
> background there is a measurable performance cost to using
> ReusableParameterizedMessages instead of ParameterizedMessages due to
> formatting on the application thread
> (MutableLogEvent/RingBufferLogEvent.setMessage).
> I have a custom layout which does not log formatted messages in most cases,
> but the format string and parameter values separately in order to analyze
> values logged over time bucketed by logger name and format string. In this
> case the formatting is unnecessary work. It is possible to implement a custom
> message factory which doesn't format message data, however that would break
> the ability to add a standard pattern layout in addition to the custom
> formatter.
> h2. Proposed Design
> Our reusable events (MutableLogEvent and RingBufferLogEvent) currently
> capture most of the required information, the format string and parameter
> array, but are missing a bit of context for how the original message
> implementation would format that data.
> ReusableMessage implementations may optionally extend
> "MessageContentFormatterProvider"
> {code:java}
> interface MessageContentFormatterProvider {
> MessageContentFormatter getMessageContentFormatter();
> }{code}
> Where MessageContentFormatter takes the form:
> {code:java}
> interface MessageContentFormatter {
> void appendTo(StringBuilder dest, String format, Object[] params, short
> paramCount);
> }{code}
> Reusable log event implementations will be updated to hold a reference to the
> content formatter (instead of formatting to the local event buffer) when
> asynchronous formatting is enabled _and_ the message is an instance of
> MessageContentFormatterProvider.
>
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)