JAVA几种拼接数组的耗时的测试

先说结论:忽略其它因素,仅从消耗时间上对比,利用List拼接最快。

JAVA拼接数组的方法有很多种:

1、纯用数组的形式 - byte[]

2、转成16进制字符串,用字符串拼接 - String

3、转成16进制字符串,用StringBuffer拼接 - StringBuffer

4、用集合的形式 - ArrayList<Byte>

测试代码如下:

package com.zzztest;

import java.util.ArrayList;
import java.util.List;

import com._tool.Hex;
import com._tool.Time;
import com._tool.z;

public class Test {
	
	public static void main(String[] args){
		byte[] bs = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
		  ,31,32,33,34,35,36,37,38,39,40,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10};
		z.print("0-beg:", Time.getNowTime("0"));
		byte[] rs1 = {};
		for(int a=0; a<10000; a++) {
			byte[] bsTemp = new byte[rs1.length + bs.length];
			for(int i=0; i< rs1.length ; i++) {
				bsTemp[i] = rs1[i];
			}
			for(int i=rs1.length; i<bsTemp.length; i++) {
				bsTemp[i] = bs[i-rs1.length];
			}
			rs1 = bsTemp;
		}
//		z.print("rs1.length:", rs1.length); // -> rs1.length:500000
		z.print("1-arr:", Time.getNowTime("0"));
		String ss="";
		for(int a=0; a<10000; a++) {
			ss += Hex.bytesToHexString(bs); // 这里不能用new String(bs)和下面的ss.getBytes(),发现当byte是负值时会出错。
		}
		byte[] rs2 = Hex.hexStringToBytes(ss); //ss.getBytes();
//		z.print("rs2.length:", rs2.length); // -> rs2.length:500000
		z.print("2-str:", Time.getNowTime("0"));
		StringBuffer sb = new StringBuffer();
		for(int a=0; a<10000; a++) {
			sb.append(Hex.bytesToHexString(bs));
		}
		byte[] rs3 = Hex.hexStringToBytes(sb.toString());
//		z.print("rs3.length:", rs3.length); // -> rs3.length:500000
		z.print("3-buf:", Time.getNowTime("0"));
		List<Byte> lb = new ArrayList<>();
		for(int a=0; a<10000; a++) {
			for(int i=0; i<bs.length; i++) {
				lb.add(bs[i]);
			}
		}
		z.print("4-000:", Time.getNowTime("0"));
		byte[] rs4 = new byte[lb.size()];
		for(int i=0; i<lb.size(); i++) {
			rs4[i] = lb.get(i);
		}
		z.print("4-lst:", Time.getNowTime("0"));
//		z.print("rs4.length:",rs4.length); // -> rs4.length:500000
}

首先我们把每一组循环10000次的for注掉,在方法最后加上以下代码打印一下这四种的结果:


		z.print("rs1:", rs1);
		z.print("rs2:", rs2);
		z.print("rs3:", rs3);
		z.print("rs4:", rs4);
// 打印结果:
//		2023-10-11 16:24:41.414/com.zzztest.Test/55 -> rs1:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]
//		2023-10-11 16:24:41.414/com.zzztest.Test/56 -> rs2:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]
//		2023-10-11 16:24:41.414/com.zzztest.Test/57 -> rs3:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]
//		2023-10-11 16:24:41.415/com.zzztest.Test/58 -> rs4:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]

我们发现打印出来的rs1 - rs4完全相同与原数组bs完全相同,说明这四种方式都可行,都能得到正确的结果。

注:在测试时发现不能使用new String(bs)和ss.getBytes(),因为这样得到的结果是错误的:

打印语句:z.print("rs2.length:", rs2.length, ",rs2:", rs2);

打印结果:2023-10-11 16:47:58.722/com.zzztest.Test/35 -> rs2.length:70,rs2:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,-17,-65,-67,-17,-65,-67,-17,-65,-67,-17,-65,-67,-17,-65,-67,-17,-65,-67,-17,-65,-67,-17,-65,-67,-17,-65,-67,-17,-65,-67]

这里 rs2的长度是70,与原数组bs长度50不相符,其结果不正确。

执行上述代码测试4种方法的耗时如下:

//2023-10-11 16:52:38.837/com.zzztest.Test/15 -> 0-beg:2023-10-11 16:52:38.746
//2023-10-11 16:52:39.599/com.zzztest.Test/28 -> 1-arr:2023-10-11 16:52:39.599
//2023-10-11 16:52:48.484/com.zzztest.Test/35 -> 2-str:2023-10-11 16:52:48.484
//2023-10-11 16:52:48.526/com.zzztest.Test/42 -> 3-buf:2023-10-11 16:52:48.526
//2023-10-11 16:52:48.533/com.zzztest.Test/49 -> 4-000:2023-10-11 16:52:48.532
//2023-10-11 16:52:48.539/com.zzztest.Test/54 -> 4-lst:2023-10-11 16:52:48.539

从结果可见,

方法1(纯数组拼接)耗时:39599 - 38746 = 853ms

方法2(String拼接)耗时:48484 - 39599 = 8885ms

方法3(StringBuffer拼接)耗时:48526 - 48484 = 42ms

方法4(List集合add)耗时:48539 - 48526 = 13ms

    反复测试了几次,方法4耗时波动在13-16ms,这中间多打印了一次4-000,是因为如果最终结果需要转化为byte数组,则一共耗时13-16ms,如果不需要转化成byte数组,直接拿这个ArrayList也可以使用,则只需耗时6-8ms。

附加:

    以上测试只是单纯测试每种方法执行时所消耗的时间,这里并未考虑其它因素,例如方法执行时CPU的消耗,内存的消耗,以及方法执行之后所产生的垃圾多少等问题。

关于工具类Hex的两个方法如下:

	// byte数组转成16进制字符串
	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return "";
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString().toUpperCase();
	}

	// 16进制字符串转成byte数组
	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || "".equals(hexString)) {
			byte[] bs = {};
			return bs;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值