Skip to content

Commit d5b30df

Browse files
authored
add benchmark for simplifying sort (#1088)
Verify performance behavior of #1079. Case with two tags is quite a bit slower with the simplification.
1 parent 5e44940 commit d5b30df

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
* Copyright 2014-2023 Netflix, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.netflix.spectator.perf;
17+
18+
import org.openjdk.jmh.annotations.Benchmark;
19+
import org.openjdk.jmh.annotations.Scope;
20+
import org.openjdk.jmh.annotations.State;
21+
import org.openjdk.jmh.infra.Blackhole;
22+
23+
import java.util.Arrays;
24+
25+
/**
26+
* <pre>
27+
* sort1_single thrpt 5 231987417.092 ± 1461766.430 ops/s
28+
* sort2_single thrpt 5 231390816.374 ± 2900091.223 ops/s
29+
*
30+
* sort1_two thrpt 5 127862169.706 ± 3004299.720 ops/s
31+
* sort2_two thrpt 5 107286992.610 ± 499836.589 ops/s
32+
*
33+
* sort1_four thrpt 5 45448061.771 ± 214688.930 ops/s
34+
* sort2_four thrpt 5 45801768.604 ± 399120.395 ops/s
35+
*
36+
* sort1_many thrpt 5 7013914.451 ± 476174.932 ops/s
37+
* sort2_many thrpt 5 7093001.872 ± 136273.382 ops/s
38+
* </pre>
39+
*/
40+
@State(Scope.Thread)
41+
public class ArrayTagSetSort {
42+
43+
private static void insertionSort1(String[] ts, int length) {
44+
if (length == 4) {
45+
// Two key/value pairs, swap if needed
46+
if (ts[0].compareTo(ts[2]) > 0) {
47+
// Swap key
48+
String tmp = ts[0];
49+
ts[0] = ts[2];
50+
ts[2] = tmp;
51+
52+
// Swap value
53+
tmp = ts[1];
54+
ts[1] = ts[3];
55+
ts[3] = tmp;
56+
}
57+
} else if (length > 4) {
58+
// One entry is already sorted. Two entries handled above, for larger arrays
59+
// use insertion sort.
60+
for (int i = 2; i < length; i += 2) {
61+
String k = ts[i];
62+
String v = ts[i + 1];
63+
int j = i - 2;
64+
for (; j >= 0 && ts[j].compareTo(k) > 0; j -= 2) {
65+
ts[j + 2] = ts[j];
66+
ts[j + 3] = ts[j + 1];
67+
}
68+
ts[j + 2] = k;
69+
ts[j + 3] = v;
70+
}
71+
}
72+
}
73+
74+
private static void insertionSort2(String[] ts, int length) {
75+
for (int i = 2; i < length; i += 2) {
76+
String k = ts[i];
77+
String v = ts[i + 1];
78+
int j = i - 2;
79+
for (; j >= 0 && ts[j].compareTo(k) > 0; j -= 2) {
80+
ts[j + 2] = ts[j];
81+
ts[j + 3] = ts[j + 1];
82+
}
83+
ts[j + 2] = k;
84+
ts[j + 3] = v;
85+
}
86+
}
87+
88+
private final String[] tagsArraySingle = new String[] {
89+
"country", "US"
90+
};
91+
92+
private final String[] tagsArrayTwo = new String[] {
93+
"status", "200",
94+
"client", "ab"
95+
};
96+
97+
private final String[] tagsArrayFour = new String[] {
98+
"country", "US",
99+
"device", "xbox",
100+
"status", "200",
101+
"client", "ab"
102+
};
103+
104+
private final String[] tagsArrayMany = new String[] {
105+
"nf.app", "test_app",
106+
"nf.cluster", "test_app-main",
107+
"nf.asg", "test_app-main-v042",
108+
"nf.stack", "main",
109+
"nf.ami", "ami-0987654321",
110+
"nf.region", "us-east-1",
111+
"nf.zone", "us-east-1e",
112+
"nf.node", "i-1234567890",
113+
"country", "US",
114+
"device", "xbox",
115+
"status", "200",
116+
"client", "ab"
117+
};
118+
119+
@Benchmark
120+
public void sort1_single(Blackhole bh) {
121+
String[] tags = Arrays.copyOf(tagsArraySingle, tagsArraySingle.length);
122+
insertionSort1(tags, tags.length);
123+
bh.consume(tags);
124+
}
125+
126+
@Benchmark
127+
public void sort2_single(Blackhole bh) {
128+
String[] tags = Arrays.copyOf(tagsArraySingle, tagsArraySingle.length);
129+
insertionSort2(tags, tags.length);
130+
bh.consume(tags);
131+
}
132+
133+
@Benchmark
134+
public void sort1_two(Blackhole bh) {
135+
String[] tags = Arrays.copyOf(tagsArrayTwo, tagsArrayTwo.length);
136+
insertionSort1(tags, tags.length);
137+
bh.consume(tags);
138+
}
139+
140+
@Benchmark
141+
public void sort2_two(Blackhole bh) {
142+
String[] tags = Arrays.copyOf(tagsArrayTwo, tagsArrayTwo.length);
143+
insertionSort2(tags, tags.length);
144+
bh.consume(tags);
145+
}
146+
147+
@Benchmark
148+
public void sort1_four(Blackhole bh) {
149+
String[] tags = Arrays.copyOf(tagsArrayFour, tagsArrayFour.length);
150+
insertionSort1(tags, tags.length);
151+
bh.consume(tags);
152+
}
153+
154+
@Benchmark
155+
public void sort2_four(Blackhole bh) {
156+
String[] tags = Arrays.copyOf(tagsArrayFour, tagsArrayFour.length);
157+
insertionSort2(tags, tags.length);
158+
bh.consume(tags);
159+
}
160+
161+
@Benchmark
162+
public void sort1_many(Blackhole bh) {
163+
String[] tags = Arrays.copyOf(tagsArrayMany, tagsArrayMany.length);
164+
insertionSort1(tags, tags.length);
165+
bh.consume(tags);
166+
}
167+
168+
@Benchmark
169+
public void sort2_many(Blackhole bh) {
170+
String[] tags = Arrays.copyOf(tagsArrayMany, tagsArrayMany.length);
171+
insertionSort2(tags, tags.length);
172+
bh.consume(tags);
173+
}
174+
}

0 commit comments

Comments
 (0)