@@ -63,9 +63,10 @@ public void onStart(Context parentContext, ReadWriteSpan span) {
6363
6464 span .setAttribute (ATTRIBUTE_KEY_PROFILE_ID , strProfileId );
6565 asprof .setTracingContext (spanId , spanName );
66+ // W3C trace ID is 32 hex chars (128 bits). Parse directly into two longs
67+ // to avoid the String#substring allocations on this hot path.
6668 String traceId = span .getSpanContext ().getTraceId ();
67- asprof .setTraceId (Long .parseUnsignedLong (traceId .substring (0 , 16 ), 16 ),
68- Long .parseUnsignedLong (traceId .substring (16 , 32 ), 16 ));
69+ asprof .setTraceId (parseHex64 (traceId , 0 ), parseHex64 (traceId , 16 ));
6970 }
7071
7172 @ Override
@@ -88,6 +89,25 @@ public static long parseSpanId(String strProfileId) {
8889 }
8990 }
9091
92+ static long parseHex64 (String s , int offset ) {
93+ long result = 0L ;
94+ for (int i = 0 ; i < 16 ; i ++) {
95+ int c = s .charAt (offset + i );
96+ int nibble ;
97+ if (c >= '0' && c <= '9' ) {
98+ nibble = c - '0' ;
99+ } else if (c >= 'a' && c <= 'f' ) {
100+ nibble = c - 'a' + 10 ;
101+ } else if (c >= 'A' && c <= 'F' ) {
102+ nibble = c - 'A' + 10 ;
103+ } else {
104+ throw new NumberFormatException ("invalid hex char in trace_id at index " + (offset + i ));
105+ }
106+ result = (result << 4 ) | nibble ;
107+ }
108+ return result ;
109+ }
110+
91111 public static boolean isRootSpan (ReadableSpan span ) {
92112 SpanContext parent = span .getParentSpanContext ();
93113 boolean noParent = parent == SpanContext .getInvalid ();
0 commit comments