[英]Is there is a faster alternative for Integer.toString(myInt).getBytes(US_ASCII)?
用戶向我發送byte / short / int / long
值。 我必須將它作為POST HTTP請求的一部分發送,我必須將數字作為字符串發送。
所以現在我做下一個:
//simplified version
byte[] data = Integer.toString(myInt).getBytes(US_ASCII);
sendPost(data);
我正在尋找更快的替代方案
Integer.toString(myInt).getBytes(US_ASCII);
因為此流創建char[]
, String
和byte[]
對象。 雖然我只需要byte[]
。 我想知道是否有更快/更好的替代方案。
這個解決方案非常簡單。
import java.util.Arrays; // Needed only for demo purposes
public class LongToBytes
{
private static final byte ZERO = '0';
private static final byte MINUS = '-';
public static byte[] convert(long value)
{
// -------------------------------------
// Manage some particular value directly
// abs(Long.MIN_VALUE) remains negative
// -------------------------------------
if ((value >= 0) && (value < 10))
return (new byte[]{(byte)(ZERO + value)});
else if ((value > -10) && (value < 0))
return (new byte[] {MINUS, (byte)(ZERO - value)});
else if (value == Long.MIN_VALUE)
return (Long.toString(value).getBytes());
// -----------------------------------------------------------------
// Initialize result
// The longest value (Long.MIN_VALUE+1) is composed of 20 characters
// -----------------------------------------------------------------
byte[] array;
array = new byte[20];
// ---------------------------
// Keep track of eventual sign
// ---------------------------
boolean negative;
negative = (value < 0);
if (negative)
value = -value;
// ----------------------
// Fill array (backwards)
// ----------------------
int size;
size = 0;
while (value > 0)
{
array[size] = (byte)((value % 10) + ZERO);
size++;
value /= 10;
}
// -------------------
// Add sign eventually
// -------------------
if (negative)
{
array[size] = MINUS;
size++;
}
// -------------------------------------------------------------
// Compose result, giving it the correct length and reversing it
// -------------------------------------------------------------
byte[] result;
int counter;
result = new byte[size];
for (counter = 0; counter < size; counter++)
result[size - counter - 1] = array[counter];
// ----
// Done
// ----
return (result);
} // convert
public static void main(String[] args)
{
try
{
long value;
value = Long.parseLong(args[0]);
System.out.println(value);
System.out.println(Arrays.toString(convert(value)));
}
catch (Exception exception)
{
exception.printStackTrace();
}
}
} // class LongToBytes
UPDATE
我使用System.nanoTime()
作為秒表,在超過100.000.000的循環中分別檢查了兩種方式(上面的方法和Long.toString().getBytes()
)的性能。
傳遞0,上述方法快約500倍。
相對較小的值(在-10.000和10.000之間)具有約60%的增益。
巨大的值(靠近Long.MIN_VALUE和Long.MAX_VALUE)的增益約為40%。
更新2
分別管理特定值(介於-9和9之間以及值Long.MIN_VALUE),情況稍微好一些。
我更新了方法的實現。
您可以將整數直接格式化為字節數組,這是一個簡單的操作,因為數字在ASCII diapason中從48到57
例如:
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class FormatInteger {
private static final byte ZERRO = 48;
private static final byte MINUS = 45;
private static String MIN_VALUE = "-9223372036854775808";
private static String MAX_VALUE = "9223372036854775807";
public static void toAsciiString(long val, byte[] to) {
if (0 == val) {
to[0] = ZERRO;
to[1] = 0;
} else if (val == Long.MIN_VALUE) {
byte min[] = MIN_VALUE.getBytes(StandardCharsets.US_ASCII);
System.arraycopy(min, 0, to, 0, min.length);
} else if(val == Long.MAX_VALUE) {
byte max[] = MAX_VALUE.getBytes(StandardCharsets.US_ASCII);
System.arraycopy(max, 0, to, 0, max.length);
} else {
boolean sign = val < 0;
if (sign) {
val *= -1L;
}
int pos = to.length - 1;
to[pos--] = 0;
while (val != 0) {
to[pos--] = (byte) (ZERRO + (val % 10));
val /= 10;
}
if (sign) {
to[pos] = MINUS;
} else {
++pos;
}
System.arraycopy(to, pos, to, 0, (to.length - pos) );
Arrays.fill(to, (to.length - pos), to.length - 1, (byte) 0);
}
}
public static void main(String[] args) {
byte[] tmp = new byte[21];
toAsciiString(0,tmp);
System.out.println( new String(tmp, StandardCharsets.US_ASCII) );
toAsciiString(1234567890,tmp);
System.out.println( new String(tmp, StandardCharsets.US_ASCII) );
toAsciiString(-1234567890,tmp);
System.out.println( new String(tmp, StandardCharsets.US_ASCII) );
toAsciiString(Long.MIN_VALUE, tmp);
System.out.println(new String(tmp, StandardCharsets.US_ASCII));
toAsciiString(Long.MAX_VALUE, tmp);
System.out.println(new String(tmp, StandardCharsets.US_ASCII));
}
}
只是一個想法
int digits = getNumberOfDifits(number);
byte[] out = new byte[digits];
for (int j = digits - 1; j >= 0; j--) {
int rem = number % 10;
out[j] = getByteForDigit(rem);
number = number / 10;
}
return out
堆中沒有輔助對象,堆棧中處理的所有內容
這是一種可能性。 這始終比Integer.toString()
方法更快。
public static byte[] getBytes(long value) {
int sign = 0;
if (value < 0) {
sign = 1;
value = -value;
}
long temp = 10L;
int chars = 1;
for (int i = 1; i < 20; i++) {
if (value < temp) {
chars = i + sign;
break;
}
temp *= 10;
}
byte[] bytes = new byte[chars];
int i = 0;
while (value > 0) {
bytes[chars - i - 1] = (byte) ((value % 10) + '0');
value /= 10;
i++;
}
if (sign == 1) {
bytes[0] = '-';
}
return bytes;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.