Skip to content

Commit 6d28a93

Browse files
core: simplify timeout header processing
Changes slightly improve performance Benchmark (serialized) Mode Cnt Score Error Units GrpcUtilBenchmark.encodeNew 1000n sample 336623 51.718 ± 1.417 ns/op GrpcUtilBenchmark.encodeNew 1000u sample 236574 77.555 ± 20.875 ns/op GrpcUtilBenchmark.encodeNew 1000m sample 224392 71.155 ± 1.600 ns/op GrpcUtilBenchmark.encodeNew 1000S sample 229616 67.269 ± 2.037 ns/op GrpcUtilBenchmark.encodeNew 1000M sample 215301 70.282 ± 1.933 ns/op GrpcUtilBenchmark.encodeNew 1000H sample 225063 73.679 ± 20.430 ns/op GrpcUtilBenchmark.encodeOld 1000n sample 311832 85.519 ± 1.729 ns/op GrpcUtilBenchmark.encodeOld 1000u sample 291613 92.320 ± 1.732 ns/op GrpcUtilBenchmark.encodeOld 1000m sample 271871 93.447 ± 1.872 ns/op GrpcUtilBenchmark.encodeOld 1000S sample 234932 117.956 ± 16.810 ns/op GrpcUtilBenchmark.encodeOld 1000M sample 224636 124.310 ± 20.249 ns/op GrpcUtilBenchmark.encodeOld 1000H sample 226764 130.803 ± 19.211 ns/op GrpcUtilBenchmark.parseNew 1000n sample 320709 60.480 ± 1.303 ns/op GrpcUtilBenchmark.parseNew 1000u sample 316349 64.447 ± 13.673 ns/op GrpcUtilBenchmark.parseNew 1000m sample 318209 61.705 ± 2.580 ns/op GrpcUtilBenchmark.parseNew 1000S sample 319629 59.342 ± 1.758 ns/op GrpcUtilBenchmark.parseNew 1000M sample 305715 59.362 ± 1.489 ns/op GrpcUtilBenchmark.parseNew 1000H sample 314919 60.224 ± 1.563 ns/op GrpcUtilBenchmark.parseOld 1000n sample 279243 64.040 ± 1.510 ns/op GrpcUtilBenchmark.parseOld 1000u sample 278008 71.313 ± 13.620 ns/op GrpcUtilBenchmark.parseOld 1000m sample 272633 67.872 ± 2.967 ns/op GrpcUtilBenchmark.parseOld 1000S sample 280955 63.966 ± 2.490 ns/op GrpcUtilBenchmark.parseOld 1000M sample 257645 71.329 ± 2.117 ns/op GrpcUtilBenchmark.parseOld 1000H sample 282510 68.425 ± 17.650 ns/op
1 parent 8894769 commit 6d28a93

File tree

1 file changed

+31
-41
lines changed

1 file changed

+31
-41
lines changed

core/src/main/java/io/grpc/internal/GrpcUtil.java

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,6 @@
4949
import java.net.HttpURLConnection;
5050
import java.net.URI;
5151
import java.net.URISyntaxException;
52-
import java.util.AbstractMap.SimpleImmutableEntry;
53-
import java.util.Arrays;
54-
import java.util.Collections;
55-
import java.util.HashMap;
56-
import java.util.List;
57-
import java.util.Map;
58-
import java.util.Map.Entry;
5952
import java.util.concurrent.ExecutorService;
6053
import java.util.concurrent.Executors;
6154
import java.util.concurrent.ScheduledExecutorService;
@@ -490,51 +483,48 @@ public Stopwatch get() {
490483
@VisibleForTesting
491484
static class TimeoutMarshaller implements Metadata.AsciiMarshaller<Long> {
492485

493-
@SuppressWarnings("unchecked") // asList uses an array which doesn't handle generics
494-
private static final List<Map.Entry<Character, TimeUnit>> SERIALIZE_ORDER
495-
= Collections.unmodifiableList(Arrays.<Entry<Character, TimeUnit>>asList(
496-
new SimpleImmutableEntry<Character, TimeUnit>('n', TimeUnit.NANOSECONDS),
497-
new SimpleImmutableEntry<Character, TimeUnit>('u', TimeUnit.MICROSECONDS),
498-
new SimpleImmutableEntry<Character, TimeUnit>('m', TimeUnit.MILLISECONDS),
499-
new SimpleImmutableEntry<Character, TimeUnit>('S', TimeUnit.SECONDS),
500-
new SimpleImmutableEntry<Character, TimeUnit>('M', TimeUnit.MINUTES),
501-
new SimpleImmutableEntry<Character, TimeUnit>('H', TimeUnit.HOURS)));
502-
503-
private static final Map<Character, TimeUnit> UNITS = createUnits();
504-
505-
private static Map<Character, TimeUnit> createUnits() {
506-
Map<Character, TimeUnit> units = new HashMap<Character, TimeUnit>();
507-
for (Entry<Character, TimeUnit> unit : SERIALIZE_ORDER) {
508-
units.put(unit.getKey(), unit.getValue());
509-
}
510-
return Collections.unmodifiableMap(units);
511-
}
512-
513486
@Override
514487
public String toAsciiString(Long timeoutNanos) {
515-
checkArgument(timeoutNanos >= 0, "Negative timeout");
516-
// the smallest integer with 9 digits
517-
int cutoff = 100000000;
518-
for (Entry<Character, TimeUnit> unit : SERIALIZE_ORDER) {
519-
long timeout = unit.getValue().convert(timeoutNanos, TimeUnit.NANOSECONDS);
520-
if (timeout < cutoff) {
521-
return Long.toString(timeout) + unit.getKey();
522-
}
488+
long cutoff = 100000000;
489+
if (timeoutNanos < 0) {
490+
throw new IllegalArgumentException("Timeout too small");
491+
} else if (timeoutNanos < cutoff) {
492+
return TimeUnit.NANOSECONDS.toNanos(timeoutNanos) + "n";
493+
} else if (timeoutNanos < cutoff * 1000L) {
494+
return TimeUnit.NANOSECONDS.toMicros(timeoutNanos) + "u";
495+
} else if (timeoutNanos < cutoff * 1000L * 1000L) {
496+
return TimeUnit.NANOSECONDS.toMillis(timeoutNanos) + "m";
497+
} else if (timeoutNanos < cutoff * 1000L * 1000L * 1000L) {
498+
return TimeUnit.NANOSECONDS.toSeconds(timeoutNanos) + "S";
499+
} else if (timeoutNanos < cutoff * 1000L * 1000L * 1000L * 60L) {
500+
return TimeUnit.NANOSECONDS.toMinutes(timeoutNanos) + "M";
501+
} else {
502+
return TimeUnit.NANOSECONDS.toHours(timeoutNanos) + "H";
523503
}
524-
throw new IllegalArgumentException("Timeout too large");
525504
}
526505

527506
@Override
528507
public Long parseAsciiString(String serialized) {
529508
checkArgument(serialized.length() > 0, "empty timeout");
530509
checkArgument(serialized.length() <= 9, "bad timeout format");
531-
String valuePart = serialized.substring(0, serialized.length() - 1);
510+
long value = Long.parseLong(serialized.substring(0, serialized.length() - 1));
532511
char unit = serialized.charAt(serialized.length() - 1);
533-
TimeUnit timeUnit = UNITS.get(unit);
534-
if (timeUnit != null) {
535-
return timeUnit.toNanos(Long.parseLong(valuePart));
512+
switch (unit) {
513+
case 'n':
514+
return TimeUnit.NANOSECONDS.toNanos(value);
515+
case 'u':
516+
return TimeUnit.MICROSECONDS.toNanos(value);
517+
case 'm':
518+
return TimeUnit.MILLISECONDS.toNanos(value);
519+
case 'S':
520+
return TimeUnit.SECONDS.toNanos(value);
521+
case 'M':
522+
return TimeUnit.MINUTES.toNanos(value);
523+
case 'H':
524+
return TimeUnit.HOURS.toNanos(value);
525+
default:
526+
throw new IllegalArgumentException(String.format("Invalid timeout unit: %s", unit));
536527
}
537-
throw new IllegalArgumentException(String.format("Invalid timeout unit: %s", unit));
538528
}
539529
}
540530

0 commit comments

Comments
 (0)