1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.pgm.debug;
45
46 import static java.nio.charset.StandardCharsets.UTF_8;
47 import static org.eclipse.jgit.lib.Constants.HEAD;
48 import static org.eclipse.jgit.lib.Constants.MASTER;
49 import static org.eclipse.jgit.lib.Constants.R_HEADS;
50 import static org.eclipse.jgit.lib.Ref.Storage.NEW;
51 import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
52
53 import java.io.BufferedReader;
54 import java.io.FileInputStream;
55 import java.io.FileNotFoundException;
56 import java.io.IOException;
57 import java.io.InputStreamReader;
58
59 import org.eclipse.jgit.internal.storage.io.BlockSource;
60 import org.eclipse.jgit.internal.storage.reftable.RefCursor;
61 import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
62 import org.eclipse.jgit.lib.ObjectId;
63 import org.eclipse.jgit.lib.ObjectIdRef;
64 import org.eclipse.jgit.lib.Ref;
65 import org.eclipse.jgit.lib.SymbolicRef;
66 import org.eclipse.jgit.pgm.Command;
67 import org.eclipse.jgit.pgm.TextBuiltin;
68 import org.eclipse.jgit.util.RefList;
69 import org.kohsuke.args4j.Argument;
70 import org.kohsuke.args4j.Option;
71
72 @Command
73 class BenchmarkReftable extends TextBuiltin {
74 enum Test {
75 SCAN,
76 SEEK_COLD, SEEK_HOT,
77 BY_ID_COLD, BY_ID_HOT;
78 }
79
80 @Option(name = "--tries")
81 private int tries = 10;
82
83 @Option(name = "--test")
84 private Test test = Test.SCAN;
85
86 @Option(name = "--ref")
87 private String ref;
88
89 @Option(name = "--object-id")
90 private String objectId;
91
92 @Argument(index = 0)
93 private String lsRemotePath;
94
95 @Argument(index = 1)
96 private String reftablePath;
97
98 @Override
99 protected void run() throws Exception {
100 switch (test) {
101 case SCAN:
102 scan();
103 break;
104
105 case SEEK_COLD:
106 seekCold(ref);
107 break;
108 case SEEK_HOT:
109 seekHot(ref);
110 break;
111
112 case BY_ID_COLD:
113 byIdCold(ObjectId.fromString(objectId));
114 break;
115 case BY_ID_HOT:
116 byIdHot(ObjectId.fromString(objectId));
117 break;
118 }
119 }
120
121 private void printf(String fmt, Object... args) throws IOException {
122 errw.println(String.format(fmt, args));
123 }
124
125 @SuppressWarnings({ "nls", "boxing" })
126 private void scan() throws Exception {
127 long start, tot;
128
129 start = System.currentTimeMillis();
130 for (int i = 0; i < tries; i++) {
131 readLsRemote();
132 }
133 tot = System.currentTimeMillis() - start;
134 printf("%12s %10d ms %6d ms/run", "packed-refs", tot, tot / tries);
135
136 start = System.currentTimeMillis();
137 for (int i = 0; i < tries; i++) {
138 try (FileInputStream in = new FileInputStream(reftablePath);
139 BlockSource src = BlockSource.from(in);
140 ReftableReader reader = new ReftableReader(src)) {
141 try (RefCursor rc = reader.allRefs()) {
142 while (rc.next()) {
143 rc.getRef();
144 }
145 }
146 }
147 }
148 tot = System.currentTimeMillis() - start;
149 printf("%12s %10d ms %6d ms/run", "reftable", tot, tot / tries);
150 }
151
152 private RefList<Ref> readLsRemote()
153 throws IOException, FileNotFoundException {
154 RefList.Builder<Ref> list = new RefList.Builder<>();
155 try (BufferedReader br = new BufferedReader(new InputStreamReader(
156 new FileInputStream(lsRemotePath), UTF_8))) {
157 Ref last = null;
158 String line;
159 while ((line = br.readLine()) != null) {
160 ObjectId id = ObjectId.fromString(line.substring(0, 40));
161 String name = line.substring(41, line.length());
162 if (last != null && name.endsWith("^{}")) {
163 last = new ObjectIdRef.PeeledTag(PACKED, last.getName(),
164 last.getObjectId(), id);
165 list.set(list.size() - 1, last);
166 continue;
167 }
168
169 if (name.equals(HEAD)) {
170 last = new SymbolicRef(name, new ObjectIdRef.Unpeeled(NEW,
171 R_HEADS + MASTER, null));
172 } else {
173 last = new ObjectIdRef.PeeledNonTag(PACKED, name, id);
174 }
175 list.add(last);
176 }
177 }
178 list.sort();
179 return list.toRefList();
180 }
181
182 @SuppressWarnings({ "nls", "boxing" })
183 private void seekCold(String refName) throws Exception {
184 long start, tot;
185
186 int lsTries = Math.min(tries, 64);
187 start = System.nanoTime();
188 for (int i = 0; i < lsTries; i++) {
189 readLsRemote().get(refName);
190 }
191 tot = System.nanoTime() - start;
192 printf("%12s %10d usec %9.1f usec/run %5d runs", "packed-refs",
193 tot / 1000,
194 (((double) tot) / lsTries) / 1000,
195 lsTries);
196
197 start = System.nanoTime();
198 for (int i = 0; i < tries; i++) {
199 try (FileInputStream in = new FileInputStream(reftablePath);
200 BlockSource src = BlockSource.from(in);
201 ReftableReader reader = new ReftableReader(src)) {
202 try (RefCursor rc = reader.seekRef(refName)) {
203 while (rc.next()) {
204 rc.getRef();
205 }
206 }
207 }
208 }
209 tot = System.nanoTime() - start;
210 printf("%12s %10d usec %9.1f usec/run %5d runs", "reftable",
211 tot / 1000,
212 (((double) tot) / tries) / 1000,
213 tries);
214 }
215
216 @SuppressWarnings({ "nls", "boxing" })
217 private void seekHot(String refName) throws Exception {
218 long start, tot;
219
220 int lsTries = Math.min(tries, 64);
221 start = System.nanoTime();
222 RefList<Ref> lsRemote = readLsRemote();
223 for (int i = 0; i < lsTries; i++) {
224 lsRemote.get(refName);
225 }
226 tot = System.nanoTime() - start;
227 printf("%12s %10d usec %9.1f usec/run %5d runs", "packed-refs",
228 tot / 1000, (((double) tot) / lsTries) / 1000, lsTries);
229
230 start = System.nanoTime();
231 try (FileInputStream in = new FileInputStream(reftablePath);
232 BlockSource src = BlockSource.from(in);
233 ReftableReader reader = new ReftableReader(src)) {
234 for (int i = 0; i < tries; i++) {
235 try (RefCursor rc = reader.seekRef(refName)) {
236 while (rc.next()) {
237 rc.getRef();
238 }
239 }
240 }
241 }
242 tot = System.nanoTime() - start;
243 printf("%12s %10d usec %9.1f usec/run %5d runs", "reftable",
244 tot / 1000, (((double) tot) / tries) / 1000, tries);
245 }
246
247 @SuppressWarnings({ "nls", "boxing" })
248 private void byIdCold(ObjectId id) throws Exception {
249 long start, tot;
250
251 int lsTries = Math.min(tries, 64);
252 start = System.nanoTime();
253 for (int i = 0; i < lsTries; i++) {
254 for (Ref r : readLsRemote()) {
255 if (id.equals(r.getObjectId())) {
256 continue;
257 }
258 }
259 }
260 tot = System.nanoTime() - start;
261 printf("%12s %10d usec %9.1f usec/run %5d runs", "packed-refs",
262 tot / 1000, (((double) tot) / lsTries) / 1000, lsTries);
263
264 start = System.nanoTime();
265 for (int i = 0; i < tries; i++) {
266 try (FileInputStream in = new FileInputStream(reftablePath);
267 BlockSource src = BlockSource.from(in);
268 ReftableReader reader = new ReftableReader(src)) {
269 try (RefCursor rc = reader.byObjectId(id)) {
270 while (rc.next()) {
271 rc.getRef();
272 }
273 }
274 }
275 }
276 tot = System.nanoTime() - start;
277 printf("%12s %10d usec %9.1f usec/run %5d runs", "reftable",
278 tot / 1000, (((double) tot) / tries) / 1000, tries);
279 }
280
281 @SuppressWarnings({ "nls", "boxing" })
282 private void byIdHot(ObjectId id) throws Exception {
283 long start, tot;
284
285 int lsTries = Math.min(tries, 64);
286 start = System.nanoTime();
287 RefList<Ref> lsRemote = readLsRemote();
288 for (int i = 0; i < lsTries; i++) {
289 for (Ref r : lsRemote) {
290 if (id.equals(r.getObjectId())) {
291 continue;
292 }
293 }
294 }
295 tot = System.nanoTime() - start;
296 printf("%12s %10d usec %9.1f usec/run %5d runs", "packed-refs",
297 tot / 1000, (((double) tot) / lsTries) / 1000, lsTries);
298
299 start = System.nanoTime();
300 try (FileInputStream in = new FileInputStream(reftablePath);
301 BlockSource src = BlockSource.from(in);
302 ReftableReader reader = new ReftableReader(src)) {
303 for (int i = 0; i < tries; i++) {
304 try (RefCursor rc = reader.byObjectId(id)) {
305 while (rc.next()) {
306 rc.getRef();
307 }
308 }
309 }
310 }
311 tot = System.nanoTime() - start;
312 printf("%12s %10d usec %9.1f usec/run %5d runs", "reftable",
313 tot / 1000, (((double) tot) / tries) / 1000, tries);
314 }
315 }