@@ -9,9 +9,12 @@ namespace Microsoft.AspNet.Hosting.Internal
9
9
{
10
10
public class FastHttpRequestIdentifierFeature : IHttpRequestIdentifierFeature
11
11
{
12
- private static readonly string _hexChars = "0123456789ABCDEF" ;
13
- // Seed the _requestId for this application instance with a random int
14
- private static long _requestId = new Random ( ) . Next ( ) ;
12
+ // Base64 encoding - but in ascii sort order for easy text based sorting
13
+ private static readonly string _encode32Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUV" ;
14
+ // Seed the _requestId for this application instance with
15
+ // the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001
16
+ // for a roughly increasing _requestId over restarts
17
+ private static long _requestId = DateTime . UtcNow . Ticks ;
15
18
16
19
private string _id = null ;
17
20
@@ -32,29 +35,31 @@ public string TraceIdentifier
32
35
}
33
36
}
34
37
35
- private static string GenerateRequestId ( long id )
38
+ private static unsafe string GenerateRequestId ( long id )
36
39
{
37
- // The following routine is ~33% faster than calling long.ToString() when testing in tight loops of
38
- // 1 million iterations.
39
- var charBuffer = new char [ sizeof ( long ) * 2 ] ;
40
- charBuffer [ 0 ] = _hexChars [ ( int ) ( id >> 60 ) & 0x0f ] ;
41
- charBuffer [ 1 ] = _hexChars [ ( int ) ( id >> 56 ) & 0x0f ] ;
42
- charBuffer [ 2 ] = _hexChars [ ( int ) ( id >> 52 ) & 0x0f ] ;
43
- charBuffer [ 3 ] = _hexChars [ ( int ) ( id >> 48 ) & 0x0f ] ;
44
- charBuffer [ 4 ] = _hexChars [ ( int ) ( id >> 44 ) & 0x0f ] ;
45
- charBuffer [ 5 ] = _hexChars [ ( int ) ( id >> 40 ) & 0x0f ] ;
46
- charBuffer [ 6 ] = _hexChars [ ( int ) ( id >> 36 ) & 0x0f ] ;
47
- charBuffer [ 7 ] = _hexChars [ ( int ) ( id >> 32 ) & 0x0f ] ;
48
- charBuffer [ 8 ] = _hexChars [ ( int ) ( id >> 28 ) & 0x0f ] ;
49
- charBuffer [ 9 ] = _hexChars [ ( int ) ( id >> 24 ) & 0x0f ] ;
50
- charBuffer [ 10 ] = _hexChars [ ( int ) ( id >> 20 ) & 0x0f ] ;
51
- charBuffer [ 11 ] = _hexChars [ ( int ) ( id >> 16 ) & 0x0f ] ;
52
- charBuffer [ 12 ] = _hexChars [ ( int ) ( id >> 12 ) & 0x0f ] ;
53
- charBuffer [ 13 ] = _hexChars [ ( int ) ( id >> 8 ) & 0x0f ] ;
54
- charBuffer [ 14 ] = _hexChars [ ( int ) ( id >> 4 ) & 0x0f ] ;
55
- charBuffer [ 15 ] = _hexChars [ ( int ) ( id >> 0 ) & 0x0f ] ;
40
+ // The following routine is ~310% faster than calling long.ToString() on x64
41
+ // and ~600% faster than calling long.ToString() on x86 in tight loops of 1 million+ iterations
42
+ // See: https://github.com/aspnet/Hosting/pull/385
56
43
57
- return new string ( charBuffer ) ;
44
+ // stackalloc to allocate array on stack rather than heap
45
+ char * charBuffer = stackalloc char [ 13 ] ;
46
+
47
+ charBuffer [ 0 ] = _encode32Chars [ ( int ) ( id >> 60 ) & 31 ] ;
48
+ charBuffer [ 1 ] = _encode32Chars [ ( int ) ( id >> 55 ) & 31 ] ;
49
+ charBuffer [ 2 ] = _encode32Chars [ ( int ) ( id >> 50 ) & 31 ] ;
50
+ charBuffer [ 3 ] = _encode32Chars [ ( int ) ( id >> 45 ) & 31 ] ;
51
+ charBuffer [ 4 ] = _encode32Chars [ ( int ) ( id >> 40 ) & 31 ] ;
52
+ charBuffer [ 5 ] = _encode32Chars [ ( int ) ( id >> 35 ) & 31 ] ;
53
+ charBuffer [ 6 ] = _encode32Chars [ ( int ) ( id >> 30 ) & 31 ] ;
54
+ charBuffer [ 7 ] = _encode32Chars [ ( int ) ( id >> 25 ) & 31 ] ;
55
+ charBuffer [ 8 ] = _encode32Chars [ ( int ) ( id >> 20 ) & 31 ] ;
56
+ charBuffer [ 9 ] = _encode32Chars [ ( int ) ( id >> 15 ) & 31 ] ;
57
+ charBuffer [ 10 ] = _encode32Chars [ ( int ) ( id >> 10 ) & 31 ] ;
58
+ charBuffer [ 11 ] = _encode32Chars [ ( int ) ( id >> 5 ) & 31 ] ;
59
+ charBuffer [ 12 ] = _encode32Chars [ ( int ) id & 31 ] ;
60
+
61
+ // string ctor overload that takes char*
62
+ return new string ( charBuffer , 0 , 13 ) ;
58
63
}
59
64
}
60
65
}
0 commit comments