Avoid creation of empty CopyOnWriteArrayList for span links#10822
Avoid creation of empty CopyOnWriteArrayList for span links#10822
Conversation
This change shares an "EMPTY" list between span when there are no span links. This avoids the construction of a CopyOnWriteArrayList, empty Object[], and internal lock Object for the common case where there are no links. This elimination of the CopyOnWriteArrayList in the empty case, reduced allocation by 5% and GC time by 7% in a span creation stress test.
amarziali
left a comment
There was a problem hiding this comment.
thanks for the improvement
| private volatile int longRunningVersion = 0; | ||
|
|
||
| protected final List<AgentSpanLink> links; | ||
| private static final List<AgentSpanLink> EMPTY = Collections.emptyList(); |
There was a problem hiding this comment.
There is an issue with SpanPointersProcessor. In fact TagsPostProcessors manipulate links directly and adding something to an emptyList will cause an UnsupportedOperationException. What can be done, is to use an empty non threadsafe list when calling tag processors if the original is empty and eventually batch adding the list at the end if the processors added something
There was a problem hiding this comment.
Few ideas here:
- There is a TODO from Doug about the processor that mutates the span links:
Does it mean it can skip span links and use tags directly?
- As processors only add span links, we can replace the span links collection by a method reference to the
addSpanLinkmethod asConsumer<SpanLink>. This will avoid exposing the span link implementation and we can keep itnulluntil there is effectively span link stored.
There was a problem hiding this comment.
That's a good catch.
I do think we need to improve the encapsulation; otherwise, these changes are going to be hard to make.
As for my prior TODO, TagMap has a bunch of methods for removeAndGetEntry, getString, stringValue, etc that could be used in the various *spanPointer methods. In theory, they could simplify the code significantly.
There was a problem hiding this comment.
On a related note, I'm curious why spanLinks was put on DDSpan rather than DDSpanContext.
It seems like it would be more consistent to put on DDSpanContext and then we wouldn't have this issue.
I also think we might be pool DDSpanContext in the future, so I'd like to avoid adding more to DDSpan.
There was a problem hiding this comment.
I'm curious why spanLinks was put on DDSpan rather than DDSpanContext.
SpanContext was supposed to describe "a span context", not to hold the span data model.
We should be able to use SpanContext as reference descriptor for spans, but they end up holding way too much data.
So when I add to implement span links, I made sure to leave them in Span, not SpanContext.
I had a look at its Javadoc and it basically should only be IDs (trace + span), sampling, a bit of (W3C) trace state and baggage, nothing else :)
BenchmarksStartupParameters
See matching parameters
SummaryFound 0 performance improvements and 0 performance regressions! Performance is the same for 64 metrics, 7 unstable metrics. Startup time reports for insecure-bankgantt
title insecure-bank - global startup overhead: candidate=1.61.0-SNAPSHOT~40fc417db7, baseline=1.61.0-SNAPSHOT~93c3816062
dateFormat X
axisFormat %s
section tracing
Agent [baseline] (1.059 s) : 0, 1059300
Total [baseline] (8.821 s) : 0, 8821382
Agent [candidate] (1.063 s) : 0, 1063068
Total [candidate] (8.838 s) : 0, 8838074
section iast
Agent [baseline] (1.224 s) : 0, 1223967
Total [baseline] (9.529 s) : 0, 9529275
Agent [candidate] (1.237 s) : 0, 1237236
Total [candidate] (9.626 s) : 0, 9626169
gantt
title insecure-bank - break down per module: candidate=1.61.0-SNAPSHOT~40fc417db7, baseline=1.61.0-SNAPSHOT~93c3816062
dateFormat X
axisFormat %s
section tracing
crashtracking [baseline] (1.2 ms) : 0, 1200
crashtracking [candidate] (1.209 ms) : 0, 1209
BytebuddyAgent [baseline] (629.253 ms) : 0, 629253
BytebuddyAgent [candidate] (631.084 ms) : 0, 631084
AgentMeter [baseline] (29.137 ms) : 0, 29137
AgentMeter [candidate] (29.33 ms) : 0, 29330
GlobalTracer [baseline] (257.389 ms) : 0, 257389
GlobalTracer [candidate] (258.262 ms) : 0, 258262
AppSec [baseline] (31.691 ms) : 0, 31691
AppSec [candidate] (31.741 ms) : 0, 31741
Debugger [baseline] (58.888 ms) : 0, 58888
Debugger [candidate] (59.039 ms) : 0, 59039
Remote Config [baseline] (595.757 µs) : 0, 596
Remote Config [candidate] (595.549 µs) : 0, 596
Telemetry [baseline] (8.715 ms) : 0, 8715
Telemetry [candidate] (8.606 ms) : 0, 8606
Flare Poller [baseline] (6.405 ms) : 0, 6405
Flare Poller [candidate] (7.119 ms) : 0, 7119
section iast
crashtracking [baseline] (1.189 ms) : 0, 1189
crashtracking [candidate] (1.191 ms) : 0, 1191
BytebuddyAgent [baseline] (793.967 ms) : 0, 793967
BytebuddyAgent [candidate] (803.35 ms) : 0, 803350
AgentMeter [baseline] (11.288 ms) : 0, 11288
AgentMeter [candidate] (11.643 ms) : 0, 11643
GlobalTracer [baseline] (246.966 ms) : 0, 246966
GlobalTracer [candidate] (249.807 ms) : 0, 249807
IAST [baseline] (25.094 ms) : 0, 25094
IAST [candidate] (25.417 ms) : 0, 25417
AppSec [baseline] (26.346 ms) : 0, 26346
AppSec [candidate] (26.664 ms) : 0, 26664
Debugger [baseline] (62.715 ms) : 0, 62715
Debugger [candidate] (62.757 ms) : 0, 62757
Remote Config [baseline] (544.341 µs) : 0, 544
Remote Config [candidate] (524.48 µs) : 0, 524
Telemetry [baseline] (15.056 ms) : 0, 15056
Telemetry [candidate] (15.208 ms) : 0, 15208
Flare Poller [baseline] (4.389 ms) : 0, 4389
Flare Poller [candidate] (4.408 ms) : 0, 4408
Startup time reports for petclinicgantt
title petclinic - global startup overhead: candidate=1.61.0-SNAPSHOT~40fc417db7, baseline=1.61.0-SNAPSHOT~93c3816062
dateFormat X
axisFormat %s
section tracing
Agent [baseline] (1.059 s) : 0, 1059055
Total [baseline] (11.047 s) : 0, 11046504
Agent [candidate] (1.062 s) : 0, 1061759
Total [candidate] (11.048 s) : 0, 11047624
section appsec
Agent [baseline] (1.242 s) : 0, 1242156
Total [baseline] (11.106 s) : 0, 11105845
Agent [candidate] (1.246 s) : 0, 1245594
Total [candidate] (11.137 s) : 0, 11137046
section iast
Agent [baseline] (1.231 s) : 0, 1231135
Total [baseline] (11.331 s) : 0, 11330714
Agent [candidate] (1.225 s) : 0, 1225207
Total [candidate] (11.328 s) : 0, 11327532
section profiling
Agent [baseline] (1.186 s) : 0, 1186246
Total [baseline] (11.016 s) : 0, 11015656
Agent [candidate] (1.177 s) : 0, 1177500
Total [candidate] (10.937 s) : 0, 10936657
gantt
title petclinic - break down per module: candidate=1.61.0-SNAPSHOT~40fc417db7, baseline=1.61.0-SNAPSHOT~93c3816062
dateFormat X
axisFormat %s
section tracing
crashtracking [baseline] (1.191 ms) : 0, 1191
crashtracking [candidate] (1.193 ms) : 0, 1193
BytebuddyAgent [baseline] (626.743 ms) : 0, 626743
BytebuddyAgent [candidate] (629.019 ms) : 0, 629019
AgentMeter [baseline] (29.033 ms) : 0, 29033
AgentMeter [candidate] (29.31 ms) : 0, 29310
GlobalTracer [baseline] (257.074 ms) : 0, 257074
GlobalTracer [candidate] (258.276 ms) : 0, 258276
AppSec [baseline] (31.81 ms) : 0, 31810
AppSec [candidate] (31.726 ms) : 0, 31726
Debugger [baseline] (59.859 ms) : 0, 59859
Debugger [candidate] (59.763 ms) : 0, 59763
Remote Config [baseline] (601.437 µs) : 0, 601
Remote Config [candidate] (597.14 µs) : 0, 597
Telemetry [baseline] (8.705 ms) : 0, 8705
Telemetry [candidate] (8.699 ms) : 0, 8699
Flare Poller [baseline] (8.048 ms) : 0, 8048
Flare Poller [candidate] (7.228 ms) : 0, 7228
section appsec
crashtracking [baseline] (1.186 ms) : 0, 1186
crashtracking [candidate] (1.196 ms) : 0, 1196
BytebuddyAgent [baseline] (655.577 ms) : 0, 655577
BytebuddyAgent [candidate] (657.095 ms) : 0, 657095
AgentMeter [baseline] (11.987 ms) : 0, 11987
AgentMeter [candidate] (12.039 ms) : 0, 12039
GlobalTracer [baseline] (257.567 ms) : 0, 257567
GlobalTracer [candidate] (258.529 ms) : 0, 258529
IAST [baseline] (23.865 ms) : 0, 23865
IAST [candidate] (23.91 ms) : 0, 23910
AppSec [baseline] (177.319 ms) : 0, 177319
AppSec [candidate] (177.575 ms) : 0, 177575
Debugger [baseline] (65.348 ms) : 0, 65348
Debugger [candidate] (65.788 ms) : 0, 65788
Remote Config [baseline] (568.582 µs) : 0, 569
Remote Config [candidate] (573.403 µs) : 0, 573
Telemetry [baseline] (8.932 ms) : 0, 8932
Telemetry [candidate] (8.962 ms) : 0, 8962
Flare Poller [baseline] (3.561 ms) : 0, 3561
Flare Poller [candidate] (3.655 ms) : 0, 3655
section iast
crashtracking [baseline] (1.193 ms) : 0, 1193
crashtracking [candidate] (1.179 ms) : 0, 1179
BytebuddyAgent [baseline] (798.964 ms) : 0, 798964
BytebuddyAgent [candidate] (794.847 ms) : 0, 794847
AgentMeter [baseline] (11.538 ms) : 0, 11538
AgentMeter [candidate] (11.298 ms) : 0, 11298
GlobalTracer [baseline] (247.758 ms) : 0, 247758
GlobalTracer [candidate] (246.743 ms) : 0, 246743
IAST [baseline] (25.21 ms) : 0, 25210
IAST [candidate] (25.042 ms) : 0, 25042
AppSec [baseline] (26.47 ms) : 0, 26470
AppSec [candidate] (26.311 ms) : 0, 26311
Debugger [baseline] (64.443 ms) : 0, 64443
Debugger [candidate] (64.253 ms) : 0, 64253
Remote Config [baseline] (530.288 µs) : 0, 530
Remote Config [candidate] (529.686 µs) : 0, 530
Telemetry [baseline] (14.276 ms) : 0, 14276
Telemetry [candidate] (14.84 ms) : 0, 14840
Flare Poller [baseline] (4.383 ms) : 0, 4383
Flare Poller [candidate] (4.268 ms) : 0, 4268
section profiling
crashtracking [baseline] (1.175 ms) : 0, 1175
crashtracking [candidate] (1.17 ms) : 0, 1170
BytebuddyAgent [baseline] (685.8 ms) : 0, 685800
BytebuddyAgent [candidate] (680.448 ms) : 0, 680448
AgentMeter [baseline] (8.674 ms) : 0, 8674
AgentMeter [candidate] (8.579 ms) : 0, 8579
GlobalTracer [baseline] (216.603 ms) : 0, 216603
GlobalTracer [candidate] (214.84 ms) : 0, 214840
AppSec [baseline] (31.976 ms) : 0, 31976
AppSec [candidate] (31.716 ms) : 0, 31716
Debugger [baseline] (63.935 ms) : 0, 63935
Debugger [candidate] (65.024 ms) : 0, 65024
Remote Config [baseline] (585.487 µs) : 0, 585
Remote Config [candidate] (582.679 µs) : 0, 583
Telemetry [baseline] (9.72 ms) : 0, 9720
Telemetry [candidate] (8.12 ms) : 0, 8120
Flare Poller [baseline] (3.451 ms) : 0, 3451
Flare Poller [candidate] (3.453 ms) : 0, 3453
ProfilingAgent [baseline] (93.286 ms) : 0, 93286
ProfilingAgent [candidate] (93.098 ms) : 0, 93098
Profiling [baseline] (93.849 ms) : 0, 93849
Profiling [candidate] (93.658 ms) : 0, 93658
LoadParameters
See matching parameters
SummaryFound 1 performance improvements and 2 performance regressions! Performance is the same for 18 metrics, 15 unstable metrics.
Request duration reports for insecure-bankgantt
title insecure-bank - request duration [CI 0.99] : candidate=1.61.0-SNAPSHOT~40fc417db7, baseline=1.61.0-SNAPSHOT~93c3816062
dateFormat X
axisFormat %s
section baseline
no_agent (1.178 ms) : 1167, 1190
. : milestone, 1178,
iast (3.166 ms) : 3125, 3207
. : milestone, 3166,
iast_FULL (5.998 ms) : 5936, 6059
. : milestone, 5998,
iast_GLOBAL (3.471 ms) : 3421, 3522
. : milestone, 3471,
profiling (2.354 ms) : 2331, 2377
. : milestone, 2354,
tracing (1.746 ms) : 1732, 1759
. : milestone, 1746,
section candidate
no_agent (1.196 ms) : 1184, 1208
. : milestone, 1196,
iast (3.163 ms) : 3120, 3206
. : milestone, 3163,
iast_FULL (6.001 ms) : 5940, 6062
. : milestone, 6001,
iast_GLOBAL (3.679 ms) : 3623, 3736
. : milestone, 3679,
profiling (2.104 ms) : 2084, 2125
. : milestone, 2104,
tracing (1.775 ms) : 1761, 1790
. : milestone, 1775,
Request duration reports for petclinicgantt
title petclinic - request duration [CI 0.99] : candidate=1.61.0-SNAPSHOT~40fc417db7, baseline=1.61.0-SNAPSHOT~93c3816062
dateFormat X
axisFormat %s
section baseline
no_agent (18.203 ms) : 18018, 18388
. : milestone, 18203,
appsec (18.855 ms) : 18663, 19046
. : milestone, 18855,
code_origins (17.96 ms) : 17780, 18140
. : milestone, 17960,
iast (17.617 ms) : 17443, 17792
. : milestone, 17617,
profiling (18.476 ms) : 18292, 18660
. : milestone, 18476,
tracing (18.04 ms) : 17860, 18219
. : milestone, 18040,
section candidate
no_agent (18.076 ms) : 17894, 18259
. : milestone, 18076,
appsec (18.941 ms) : 18749, 19132
. : milestone, 18941,
code_origins (18.327 ms) : 18144, 18511
. : milestone, 18327,
iast (17.727 ms) : 17553, 17901
. : milestone, 17727,
profiling (18.622 ms) : 18434, 18810
. : milestone, 18622,
tracing (18.27 ms) : 18089, 18451
. : milestone, 18270,
DacapoParameters
See matching parameters
SummaryFound 0 performance improvements and 0 performance regressions! Performance is the same for 10 metrics, 2 unstable metrics. Execution time for tomcatgantt
title tomcat - execution time [CI 0.99] : candidate=1.61.0-SNAPSHOT~40fc417db7, baseline=1.61.0-SNAPSHOT~93c3816062
dateFormat X
axisFormat %s
section baseline
no_agent (1.474 ms) : 1463, 1486
. : milestone, 1474,
appsec (3.844 ms) : 3621, 4067
. : milestone, 3844,
iast (2.254 ms) : 2185, 2323
. : milestone, 2254,
iast_GLOBAL (2.311 ms) : 2241, 2381
. : milestone, 2311,
profiling (2.099 ms) : 2044, 2155
. : milestone, 2099,
tracing (2.065 ms) : 2012, 2119
. : milestone, 2065,
section candidate
no_agent (1.475 ms) : 1464, 1487
. : milestone, 1475,
appsec (3.815 ms) : 3591, 4038
. : milestone, 3815,
iast (2.258 ms) : 2189, 2327
. : milestone, 2258,
iast_GLOBAL (2.3 ms) : 2230, 2369
. : milestone, 2300,
profiling (2.527 ms) : 2360, 2693
. : milestone, 2527,
tracing (2.077 ms) : 2023, 2131
. : milestone, 2077,
Execution time for biojavagantt
title biojava - execution time [CI 0.99] : candidate=1.61.0-SNAPSHOT~40fc417db7, baseline=1.61.0-SNAPSHOT~93c3816062
dateFormat X
axisFormat %s
section baseline
no_agent (14.891 s) : 14891000, 14891000
. : milestone, 14891000,
appsec (14.848 s) : 14848000, 14848000
. : milestone, 14848000,
iast (18.037 s) : 18037000, 18037000
. : milestone, 18037000,
iast_GLOBAL (17.576 s) : 17576000, 17576000
. : milestone, 17576000,
profiling (15.316 s) : 15316000, 15316000
. : milestone, 15316000,
tracing (15.285 s) : 15285000, 15285000
. : milestone, 15285000,
section candidate
no_agent (15.002 s) : 15002000, 15002000
. : milestone, 15002000,
appsec (15.107 s) : 15107000, 15107000
. : milestone, 15107000,
iast (18.244 s) : 18244000, 18244000
. : milestone, 18244000,
iast_GLOBAL (17.942 s) : 17942000, 17942000
. : milestone, 17942000,
profiling (15.008 s) : 15008000, 15008000
. : milestone, 15008000,
tracing (14.983 s) : 14983000, 14983000
. : milestone, 14983000,
|
What Does This Do
This change shares an "EMPTY" list between spans when there are no span links.
This avoids the construction of a CopyOnWriteArrayList, empty Object[], and internal lock Object for the common case where there are no links.
Motivation
This elimination of the CopyOnWriteArrayList in the empty case, reduced allocation by 5% and GC time by 7% in a span creation stress test.
Additional Notes
Contributor Checklist
type:and (comp:orinst:) labels in addition to any other useful labelsclose,fix, or any linking keywords when referencing an issueUse
solvesinstead, and assign the PR milestone to the issueJira ticket: [PROJ-IDENT]
Note: Once your PR is ready to merge, add it to the merge queue by commenting
/merge./merge -ccancels the queue request./merge -f --reason "reason"skips all merge queue checks; please use this judiciously, as some checks do not run at the PR-level. For more information, see this doc.