Skip to content

Commit 6b81a2d

Browse files
committed
Optimized Jenkin3 lookup version 2
1 parent 037e7dc commit 6b81a2d

File tree

1 file changed

+33
-33
lines changed

1 file changed

+33
-33
lines changed

sdk/eventhub/Azure.Messaging.EventHubs/src/Core/PartitionResolver.cs

+33-33
Original file line numberDiff line numberDiff line change
@@ -155,23 +155,22 @@ private static void ComputeHash(ReadOnlySpan<byte> data,
155155
uint b = a;
156156
uint c = a + seed2;
157157

158-
int tripletCount = data.Length > 12 ? (data.Length - 1) / 12 : 0;
158+
int chunks = data.Length > 12 ? (data.Length - 1) / 12 : 0;
159159

160-
int regionBytes = tripletCount * 12; // must be divisible by 4
161-
ReadOnlySpan<byte> region = data.Slice(0, regionBytes);
162-
ReadOnlySpan<uint> words = MemoryMarshal.Cast<byte, uint>(region);
163-
164-
int i = 0;
165-
for (; i < tripletCount; i++)
160+
ref byte ptr = ref MemoryMarshal.GetReference(data);
161+
for (int i = 0; i < chunks; i++)
166162
{
167-
int idx = i * 3;
168-
uint w0 = BitConverter.IsLittleEndian ? words[idx] : BinaryPrimitives.ReverseEndianness(words[idx]);
169-
uint w1 = BitConverter.IsLittleEndian
170-
? words[idx + 1]
171-
: BinaryPrimitives.ReverseEndianness(words[idx + 1]);
172-
uint w2 = BitConverter.IsLittleEndian
173-
? words[idx + 2]
174-
: BinaryPrimitives.ReverseEndianness(words[idx + 2]);
163+
uint w0 = Unsafe.ReadUnaligned<uint>(ref ptr);
164+
uint w1 = Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref ptr, 4));
165+
uint w2 = Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref ptr, 8));
166+
ptr = ref Unsafe.Add(ref ptr, 12);
167+
168+
if (!BitConverter.IsLittleEndian)
169+
{
170+
w0 = BinaryPrimitives.ReverseEndianness(w0);
171+
w1 = BinaryPrimitives.ReverseEndianness(w1);
172+
w2 = BinaryPrimitives.ReverseEndianness(w2);
173+
}
175174

176175
a += w0;
177176
b += w1;
@@ -202,48 +201,49 @@ private static void ComputeHash(ReadOnlySpan<byte> data,
202201
b += a;
203202
}
204203

205-
int byteIndex = regionBytes;
206-
int size = data.Length - byteIndex;
207-
switch (size)
204+
int consumed = chunks * 12;
205+
ref byte tail = ref Unsafe.Add(ref MemoryMarshal.GetReference(data), consumed);
206+
int left = data.Length - consumed;
207+
switch (left)
208208
{
209209
case 12:
210-
a += BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(byteIndex));
211-
b += BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(byteIndex + 4));
212-
c += BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(byteIndex + 8));
210+
a += BitConverter.IsLittleEndian ? Unsafe.ReadUnaligned<uint>(ref tail) : BinaryPrimitives.ReverseEndianness(Unsafe.ReadUnaligned<uint>(ref tail));
211+
b += BitConverter.IsLittleEndian ? Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref tail, 4)) : BinaryPrimitives.ReverseEndianness(Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref tail, 4)));
212+
c += BitConverter.IsLittleEndian ? Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref tail, 8)) : BinaryPrimitives.ReverseEndianness(Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref tail, 8)));
213213
break;
214214
case 11:
215-
c += (uint)data[byteIndex + 10] << 16;
215+
c += (uint)Unsafe.Add(ref tail, 10) << 16;
216216
goto case 10;
217217
case 10:
218-
c += (uint)data[byteIndex + 9] << 8;
218+
c += (uint)Unsafe.Add(ref tail, 9) << 8;
219219
goto case 9;
220220
case 9:
221-
c += data[byteIndex + 8];
221+
c += Unsafe.Add(ref tail, 8);
222222
goto case 8;
223223
case 8:
224-
b += BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(byteIndex + 4));
225-
a += BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(byteIndex));
224+
b += BitConverter.IsLittleEndian ? Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref tail, 4)) : BinaryPrimitives.ReverseEndianness(Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref tail, 4)));
225+
a += BitConverter.IsLittleEndian ? Unsafe.ReadUnaligned<uint>(ref tail) : BinaryPrimitives.ReverseEndianness(Unsafe.ReadUnaligned<uint>(ref tail));
226226
break;
227227
case 7:
228-
b += (uint)data[byteIndex + 6] << 16;
228+
b += (uint)Unsafe.Add(ref tail, 6) << 16;
229229
goto case 6;
230230
case 6:
231-
b += (uint)data[byteIndex + 5] << 8;
231+
b += (uint)Unsafe.Add(ref tail, 5) << 8;
232232
goto case 5;
233233
case 5:
234-
b += data[byteIndex + 4];
234+
b += Unsafe.Add(ref tail, 4);
235235
goto case 4;
236236
case 4:
237-
a += BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(byteIndex));
237+
a += BitConverter.IsLittleEndian ? Unsafe.ReadUnaligned<uint>(ref tail) : BinaryPrimitives.ReverseEndianness(Unsafe.ReadUnaligned<uint>(ref tail));
238238
break;
239239
case 3:
240-
a += (uint)data[byteIndex + 2] << 16;
240+
a += (uint)Unsafe.Add(ref tail, 2) << 16;
241241
goto case 2;
242242
case 2:
243-
a += (uint)data[byteIndex + 1] << 8;
243+
a += (uint)Unsafe.Add(ref tail, 1) << 8;
244244
goto case 1;
245245
case 1:
246-
a += data[byteIndex];
246+
a += Unsafe.Add(ref tail, 0);
247247
break;
248248
case 0:
249249
hash1 = c;

0 commit comments

Comments
 (0)