我不會建議但是,在處理很多FIX消息時,請同意Jon的意見,這很快就會增加。 下面的方法將允許填充空格的數字。如果你需要處理小數,那麼代碼會稍有不同。兩種方法之間的速度差異是因子11. ConvertToLong結果爲0個GC。以下代碼位於c#:
///<summary>
///Converts a byte[] of characters that represent a number into a .net long type. Numbers can be padded from left
/// with spaces.
///</summary>
///<param name="buffer">The buffer containing the number as characters</param>
///<param name="startIndex">The startIndex of the number component</param>
///<param name="endIndex">The EndIndex of the number component</param>
///<returns>The price will be returned as a long from the ASCII characters</returns>
public static long ConvertToLong(this byte[] buffer, int startIndex, int endIndex)
{
long result = 0;
for (int i = startIndex; i <= endIndex; i++)
{
if (buffer[i] != 0x20)
{
// 48 is the decimal value of the '0' character. So to convert the char value
// of an int to a number we subtract 48. e.g '1' = 49 -48 = 1
result = result * 10 + (buffer[i] - 48);
}
}
return result;
}
/// <summary>
/// Same as above but converting to string then to long
/// </summary>
public static long ConvertToLong2(this byte[] buffer, int startIndex, int endIndex)
{
for (int i = startIndex; i <= endIndex; i++)
{
if (buffer[i] != SpaceChar)
{
return long.Parse(System.Text.Encoding.UTF8.GetString(buffer, i, (endIndex - i) + 1));
}
}
return 0;
}
[Test]
public void TestPerformance(){
const int iterations = 200 * 1000;
const int testRuns = 10;
const int warmUp = 10000;
const string number = " 123400";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(number);
double result = 0;
for (int i = 0; i < warmUp; i++){
result = buffer.ConvertToLong(0, buffer.Length - 1);
}
for (int testRun = 0; testRun < testRuns; testRun++){
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < iterations; i++){
result = buffer.ConvertToLong(0, buffer.Length - 1);
}
sw.Stop();
Console.WriteLine("Test {4}: {0} ticks, {1}ms, 1 conversion takes = {2}μs or {3}ns. GCs: {5}", sw.ElapsedTicks,
sw.ElapsedMilliseconds, (((decimal) sw.ElapsedMilliseconds)/((decimal) iterations))*1000,
(((decimal) sw.ElapsedMilliseconds)/((decimal) iterations))*1000*1000, testRun,
GC.CollectionCount(0) + GC.CollectionCount(1) + GC.CollectionCount(2));
}
}
RESULTS
ConvertToLong:
Test 0: 9243 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
Test 1: 8339 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
Test 2: 8425 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
Test 3: 8333 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
Test 4: 8332 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
Test 5: 8331 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
Test 6: 8409 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
Test 7: 8334 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
Test 8: 8335 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
Test 9: 8331 ticks, 4ms, 1 conversion takes = 0.02000μs or 20.00000ns. GCs: 2
ConvertToLong2:
Test 0: 109067 ticks, 55ms, 1 conversion takes = 0.275000μs or 275.000000ns. GCs: 4
Test 1: 109861 ticks, 56ms, 1 conversion takes = 0.28000μs or 280.00000ns. GCs: 8
Test 2: 102888 ticks, 52ms, 1 conversion takes = 0.26000μs or 260.00000ns. GCs: 9
Test 3: 105164 ticks, 53ms, 1 conversion takes = 0.265000μs or 265.000000ns. GCs: 10
Test 4: 104083 ticks, 53ms, 1 conversion takes = 0.265000μs or 265.000000ns. GCs: 11
Test 5: 102756 ticks, 52ms, 1 conversion takes = 0.26000μs or 260.00000ns. GCs: 13
Test 6: 102219 ticks, 52ms, 1 conversion takes = 0.26000μs or 260.00000ns. GCs: 14
Test 7: 102086 ticks, 52ms, 1 conversion takes = 0.26000μs or 260.00000ns. GCs: 15
Test 8: 102672 ticks, 52ms, 1 conversion takes = 0.26000μs or 260.00000ns. GCs: 17
Test 9: 102025 ticks, 52ms, 1 conversion takes = 0.26000μs or 260.00000ns. GCs: 18
測量性能,即微基準很難並且幾乎總是出錯。如果您需要整體性能,則將字符串化是個壞主意。您應該使用'ByteBufefr.putInt'來代替。除此之外,手寫'ByteBuffer'解析將會執行,如果使用'ByteBuffer'則不會將其轉換爲byte [],這會破壞ByteBuffer本身的用途。 – bestsss 2012-02-07 07:24:53
謝謝bestss,但它是ASCII ByteBuffer,不是二進制的,所以不能使用getInt,putInt。 – Mahendra 2012-02-07 07:51:23
什麼是你稱爲ASCII byteBuffer(標準jdk中沒有這樣的類) – bestsss 2012-02-07 07:57:46