我不会建议但是,在处理很多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