You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zipkin.apache.org by ad...@apache.org on 2019/05/12 01:55:25 UTC

[incubator-zipkin] branch master updated: Reduces array copying when converting uint64 to hex strings (#2587)

This is an automated email from the ASF dual-hosted git repository.

adriancole pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-zipkin.git


The following commit(s) were added to refs/heads/master by this push:
     new 27190bf  Reduces array copying when converting uint64 to hex strings (#2587)
27190bf is described below

commit 27190bf929b8d64ad0e7b99c05bb4057c046c4f2
Author: Adrian Cole <ad...@users.noreply.github.com>
AuthorDate: Sun May 12 09:55:20 2019 +0800

    Reduces array copying when converting uint64 to hex strings (#2587)
    
    This will affect those using Brave or Thrift encoding.
---
 .../src/main/java/zipkin2/SpanBenchmarks.java      | 35 +++++++++++++++++++---
 .../main/java/zipkin2/codec/CodecBenchmarks.java   |  3 +-
 zipkin/src/main/java/zipkin2/Endpoint.java         |  5 ++--
 zipkin/src/main/java/zipkin2/Span.java             | 26 ++++++++--------
 .../main/java/zipkin2/internal/UnsafeBuffer.java   |  7 ++---
 5 files changed, 51 insertions(+), 25 deletions(-)

diff --git a/benchmarks/src/main/java/zipkin2/SpanBenchmarks.java b/benchmarks/src/main/java/zipkin2/SpanBenchmarks.java
index f31fcdc..40eed40 100644
--- a/benchmarks/src/main/java/zipkin2/SpanBenchmarks.java
+++ b/benchmarks/src/main/java/zipkin2/SpanBenchmarks.java
@@ -32,13 +32,15 @@ import org.openjdk.jmh.runner.RunnerException;
 import org.openjdk.jmh.runner.options.Options;
 import org.openjdk.jmh.runner.options.OptionsBuilder;
 
+import static zipkin2.internal.HexCodec.lowerHexToUnsignedLong;
+
 @Measurement(iterations = 5, time = 1)
 @Warmup(iterations = 10, time = 1)
 @Fork(3)
-@BenchmarkMode(Mode.Throughput)
+@BenchmarkMode(Mode.SampleTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 @State(Scope.Thread)
-@Threads(1)
+@Threads(2)
 public class SpanBenchmarks {
   static final Endpoint FRONTEND =
     Endpoint.newBuilder().serviceName("frontend").ip("127.0.0.1").build();
@@ -51,14 +53,20 @@ public class SpanBenchmarks {
     sharedBuilder = buildClientSpan().toBuilder();
   }
 
-  static final String traceIdHex = "86154a4ba6e91385";
-  static final String spanIdHex = "4d1e00c0db9010db";
+  static final String traceIdHex = "86154a4ba6e91385", spanIdHex = "4d1e00c0db9010db";
+  static final long traceId = lowerHexToUnsignedLong(traceIdHex);
+  static final long spanId = lowerHexToUnsignedLong(spanIdHex);
 
   @Benchmark
   public Span buildClientSpan() {
     return buildClientSpan(Span.newBuilder());
   }
 
+  @Benchmark
+  public Span buildClientSpan_longs() {
+    return buildClientSpan_longs(Span.newBuilder());
+  }
+
   static Span buildClientSpan(Span.Builder builder) {
     return builder
       .traceId(traceIdHex)
@@ -77,6 +85,24 @@ public class SpanBenchmarks {
       .build();
   }
 
+  static Span buildClientSpan_longs(Span.Builder builder) {
+    return builder
+      .traceId(0L, traceId)
+      .parentId(traceId)
+      .id(spanId)
+      .name("get")
+      .kind(Span.Kind.CLIENT)
+      .localEndpoint(FRONTEND)
+      .remoteEndpoint(BACKEND)
+      .timestamp(1472470996199000L)
+      .duration(207000L)
+      .addAnnotation(1472470996238000L, "ws")
+      .addAnnotation(1472470996403000L, "wr")
+      .putTag("http.path", "/api")
+      .putTag("clnt/finagle.version", "6.45.0")
+      .build();
+  }
+
   @Benchmark
   public Span buildClientSpan_clear() {
     return buildClientSpan(sharedBuilder.clear());
@@ -91,6 +117,7 @@ public class SpanBenchmarks {
   public static void main(String[] args) throws RunnerException {
     Options opt = new OptionsBuilder()
       .include(".*" + SpanBenchmarks.class.getSimpleName() + ".*")
+      .addProfiler("gc")
       .build();
 
     new Runner(opt).run();
diff --git a/benchmarks/src/main/java/zipkin2/codec/CodecBenchmarks.java b/benchmarks/src/main/java/zipkin2/codec/CodecBenchmarks.java
index d3ebbe4..7591b88 100644
--- a/benchmarks/src/main/java/zipkin2/codec/CodecBenchmarks.java
+++ b/benchmarks/src/main/java/zipkin2/codec/CodecBenchmarks.java
@@ -54,7 +54,7 @@ import zipkin2.Span;
 @Measurement(iterations = 5, time = 1)
 @Warmup(iterations = 10, time = 1)
 @Fork(3)
-@BenchmarkMode(Mode.AverageTime)
+@BenchmarkMode(Mode.SampleTime)
 @OutputTimeUnit(TimeUnit.MICROSECONDS)
 @State(Scope.Thread)
 @Threads(1)
@@ -192,6 +192,7 @@ public class CodecBenchmarks {
   public static void main(String[] args) throws RunnerException {
     Options opt = new OptionsBuilder()
       .include(".*" + CodecBenchmarks.class.getSimpleName())
+      .addProfiler("gc")
       .build();
 
     new Runner(opt).run();
diff --git a/zipkin/src/main/java/zipkin2/Endpoint.java b/zipkin/src/main/java/zipkin2/Endpoint.java
index aff60cd..be6a214 100644
--- a/zipkin/src/main/java/zipkin2/Endpoint.java
+++ b/zipkin/src/main/java/zipkin2/Endpoint.java
@@ -26,6 +26,8 @@ import java.nio.ByteBuffer;
 import java.util.Locale;
 import zipkin2.internal.Nullable;
 
+import static zipkin2.internal.UnsafeBuffer.HEX_DIGITS;
+
 /** The network context of a node in the service graph. */
 //@Immutable
 public final class Endpoint implements Serializable { // for Spark and Flink jobs
@@ -437,9 +439,6 @@ public final class Endpoint implements Serializable { // for Spark and Flink job
     return new String(buf, 0, pos);
   }
 
-  static final char[] HEX_DIGITS =
-    {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
-
   // Begin code from com.google.common.net.InetAddresses 23
   static final int IPV6_PART_COUNT = 8;
 
diff --git a/zipkin/src/main/java/zipkin2/Span.java b/zipkin/src/main/java/zipkin2/Span.java
index af25f1f..1f07e63 100644
--- a/zipkin/src/main/java/zipkin2/Span.java
+++ b/zipkin/src/main/java/zipkin2/Span.java
@@ -32,10 +32,11 @@ import java.util.logging.Logger;
 import zipkin2.codec.SpanBytesDecoder;
 import zipkin2.codec.SpanBytesEncoder;
 import zipkin2.internal.Nullable;
+import zipkin2.internal.Platform;
 
 import static java.lang.String.format;
 import static java.util.logging.Level.FINEST;
-import static zipkin2.Endpoint.HEX_DIGITS;
+import static zipkin2.internal.UnsafeBuffer.HEX_DIGITS;
 
 /**
  * A span is a single-host view of an operation. A trace is a series of spans (often RPC calls)
@@ -415,14 +416,14 @@ public final class Span implements Serializable { // for Spark and Flink jobs
      */
     public Builder traceId(long high, long low) {
       if (high == 0L && low == 0L) throw new IllegalArgumentException("empty trace ID");
-      char[] result = new char[high != 0L ? 32 : 16];
+      char[] data = Platform.get().idBuffer();
       int pos = 0;
       if (high != 0L) {
-        writeHexLong(result, pos, high);
+        writeHexLong(data, pos, high);
         pos += 16;
       }
-      writeHexLong(result, pos, low);
-      this.traceId = new String(result);
+      writeHexLong(data, pos, low);
+      this.traceId = new String(data, 0, high != 0L ? 32 : 16);
       return this;
     }
 
@@ -659,18 +660,17 @@ public final class Span implements Serializable { // for Spark and Flink jobs
   }
 
   static String padLeft(String id, int desiredLength) {
-    StringBuilder builder = new StringBuilder(desiredLength);
-    int offset = desiredLength - id.length();
-
-    for (int i = 0; i < offset; i++) builder.append('0');
-    builder.append(id);
-    return builder.toString();
+    char[] data = Platform.get().idBuffer();
+    int i = 0, length = id.length(), offset = desiredLength - length;
+    for (; i < offset; i++) data[i] = '0';
+    for (int j = 0; j < length; j++) data[i++] = id.charAt(j);
+    return new String(data, 0, desiredLength);
   }
 
   static String toLowerHex(long v) {
-    char[] data = new char[16];
+    char[] data = Platform.get().idBuffer();
     writeHexLong(data, 0, v);
-    return new String(data);
+    return new String(data, 0, 16);
   }
 
   /** Inspired by {@code okio.Buffer.writeLong} */
diff --git a/zipkin/src/main/java/zipkin2/internal/UnsafeBuffer.java b/zipkin/src/main/java/zipkin2/internal/UnsafeBuffer.java
index 8f32cd8..5089b35 100644
--- a/zipkin/src/main/java/zipkin2/internal/UnsafeBuffer.java
+++ b/zipkin/src/main/java/zipkin2/internal/UnsafeBuffer.java
@@ -26,6 +26,9 @@ import static zipkin2.internal.JsonCodec.UTF_8;
  * prior to writing, overrunning a buffer is a programming error.
  */
 public final class UnsafeBuffer {
+  public static final char[] HEX_DIGITS = {
+    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+  };
 
   public static UnsafeBuffer wrap(byte[] bytes, int pos) {
     return new UnsafeBuffer(bytes, pos);
@@ -35,10 +38,6 @@ public final class UnsafeBuffer {
     return new UnsafeBuffer(sizeInBytes);
   }
 
-  static final char[] HEX_DIGITS = {
-    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-  };
-
   private final byte[] buf;
   int pos; // visible for testing