Java 读取字节数组时出现意外的长处理时间
我有一个程序,需要处理字节数组源代码。最初,当字节数组大小为3000字节时,程序工作正常。现在,数据大小增加,阵列大小需要从3000更改为30000 10次 我制作了一个示例基准程序来测试循环时间。我认为所需的CPU时间应该根据数组大小线性增加,但基准测试程序显示,处理30000字节所需的时间比处理3000字节所需的时间多得多 这是我的基准计划。程序是否可以改进,使其仅使用大约10倍的CPU时间Java 读取字节数组时出现意外的长处理时间,java,arrays,byte,Java,Arrays,Byte,我有一个程序,需要处理字节数组源代码。最初,当字节数组大小为3000字节时,程序工作正常。现在,数据大小增加,阵列大小需要从3000更改为30000 10次 我制作了一个示例基准程序来测试循环时间。我认为所需的CPU时间应该根据数组大小线性增加,但基准测试程序显示,处理30000字节所需的时间比处理3000字节所需的时间多得多 这是我的基准计划。程序是否可以改进,使其仅使用大约10倍的CPU时间 public static void main(String args[]) int Te
public static void main(String args[])
int TestArraySize=30000;
String strFinalMessage="";
// create a dummy byte array
byte[] bytearrayMessageContent = new byte[TestArraySize];
for (int i=0; i<TestArraySize; i++) {
// fill character A-J into the dummy array
bytearrayMessageContent[i] = (byte) (i%10+65);
}
System.out.println(bytearrayMessageContent.length);
// time start time
long lngCurrentTime = System.currentTimeMillis();
// process the byte array
int intTHMessageLenAdj = TestArraySize;
try {
InputStream input = new ByteArrayInputStream(bytearrayMessageContent);
while (intTHMessageLenAdj > 0) {
// get random length of bytes to process
int RandomLength = getNextRandom();
if (RandomLength > intTHMessageLenAdj) {
RandomLength = intTHMessageLenAdj;
}
// get the bytes to be process in a byte array and process it
byte[] bytearrayMsgTrunk = new byte[RandomLength];
input.read(bytearrayMsgTrunk);
// do some logic here
strFinalMessage += new String(bytearrayMsgTrunk) + "||";
// repeat looping until all bytes are read
intTHMessageLenAdj -= RandomLength;
}
input.close();
} catch (Exception ex) {
ex.printStackTrace();
}
// time end time
lngCurrentTime = System.currentTimeMillis() - lngCurrentTime;
//System.out.println(strFinalMessage);
System.out.println(lngCurrentTime);
}
public static int getNextRandom() {
// info is arround 4 bytes size
Random random = new Random();
return random.nextInt(8);
}
嗯,这里有几个问题: 您正在对字符串使用默认的平台编码。不要那样做。指定要在字节和文本之间转换的特定字符串编码。 不要像这样在循环中连接字符串-使用StringBuilder。 您正在忽略InputStream.Read的返回值。在阅读ByteArrayInputStream时,这可能没什么问题,但您通常不应该依赖它。 每次都会创建一个新的Random实例。我相信这在Java6中是可以的,但是在早期版本中会给您重复的值。基本上,这是个坏主意。重复使用Random的一个实例。
嗯,这里有几个问题: 您正在对字符串使用默认的平台编码。不要那样做。指定要在字节和文本之间转换的特定字符串编码。 不要像这样在循环中连接字符串-使用StringBuilder。 您正在忽略InputStream.Read的返回值。在阅读ByteArrayInputStream时,这可能没什么问题,但您通常不应该依赖它。 每次都会创建一个新的Random实例。我相信这在Java6中是可以的,但是在早期版本中会给您重复的值。基本上,这是个坏主意。重复使用Random的一个实例。 我认为所需的CPU时间应该根据数组大小线性增加,但基准测试程序显示,处理30000字节所需的时间比处理3000字节所需的时间多得多 事实上,我希望它会随着阵列的大小呈二次增长。如果要分析该程序,您可能会发现大部分时间都在调用String.concat。随着阵列变大,比例也会增加 基本上,每次进行字符串连接时,都会将迄今为止积累的所有字符复制到一个新字符串中。。。扔掉前一个。不难看出代码的这一部分在**2上,其中N是数组大小 将字符串声明和连接替换为以下内容:
// allocate the builder with extra space to hold the '||' characters
StringBuilder sb= new StringBuilder(TestArraySize * 3 / 2);
...
// this replaces the concatenation.
sb.append(new String(bytearrayMsgTrunk);
sb.append("||");
...
// this does a final copy of the characters to create a new String
String strFinalMessage = sb.toString();
我认为所需的CPU时间应该根据数组大小线性增加,但基准测试程序显示,处理30000字节所需的时间比处理3000字节所需的时间多得多
事实上,我希望它会随着阵列的大小呈二次增长。如果要分析该程序,您可能会发现大部分时间都在调用String.concat。随着阵列变大,比例也会增加
基本上,每次进行字符串连接时,都会将迄今为止积累的所有字符复制到一个新字符串中。。。扔掉前一个。不难看出代码的这一部分在**2上,其中N是数组大小
将字符串声明和连接替换为以下内容:
// allocate the builder with extra space to hold the '||' characters
StringBuilder sb= new StringBuilder(TestArraySize * 3 / 2);
...
// this replaces the concatenation.
sb.append(new String(bytearrayMsgTrunk);
sb.append("||");
...
// this does a final copy of the characters to create a new String
String strFinalMessage = sb.toString();
为什么您认为需要增加缓冲区大小,因为数据大小会增加?事实并非如此。为什么您认为需要增加缓冲区大小,因为数据大小会增加?事实并非如此。可能使用stringbuilder?可能使用stringbuilder?他在每次调用getNextRandom时都创建一个新的随机对象,在每次调用getNextRandom时都创建一个新的随机对象