小段代码求优化

aotian16 2012-12-12 10:59:00
我的一个程序里有个方法比较耗时,
调试发现是new string比较耗时间,

比如以下代码
		StringBuilder sb = new StringBuilder();

long start = System.currentTimeMillis();
byte[] bytes = {1,2,3,4};
for (int i = 0; i < 100000; i++) {
String string = new String(bytes, 2, 2);
// String string = "test";
sb.append(string);
}
long end = System.currentTimeMillis();

System.out.println(end - start);


用new string的话要60毫秒,
而直接用test的话只要16毫秒,

问题是我必需从bytes中取得后面两位的数据, 前面两位没有用,
有什么办法优化吗?
...全文
348 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
lost_guy_in_scut 2012-12-12
  • 打赏
  • 举报
回复

	StringBuilder sb = new StringBuilder();
        long start = System.currentTimeMillis();
        byte[] bytes = {1,2,3,4};
        String string=null;
        byte[]  des = new byte[2]; 
        for (int i = 0; i < 100000; i++) {
        	System.arraycopy(bytes, 2, des, 0, 2);
            string =Arrays.toString(des);
            sb.append(string);
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
aotian16 2012-12-12
  • 打赏
  • 举报
回复
引用 9 楼 yUu_lean 的回复:
能改bytes的来源的方法么,把他的返回值改为char[]; 如果不能改,你每次取bytes里面的位数都确定么,每次都是最后两个么?
不能改结构, 位数不固定, 只有前面两位是无效数据
wapigzhu 2012-12-12
  • 打赏
  • 举报
回复

public static void main(String[] args) {
		long start = System.currentTimeMillis();
		byte[] bytes = { 1, 2, 3, 4 };
		byte[] target = new byte[1024 * 1024];
		int currentIndex = 0;
		for (int i = 0; i < 10000000; i++) {
			if(currentIndex + 2 > target.length){
				byte[] newTarget = new byte[target.length * 3 / 2];
				System.arraycopy(target, 0, newTarget, 0, currentIndex);
				target = newTarget;
			}
			System.arraycopy(bytes, 2, target, currentIndex, 2);
			currentIndex += 2;
		}
		String str = new String(target, 0, currentIndex);
		System.out.println(str.length());
		long end = System.currentTimeMillis();
		System.out.println(end - start);
	}
次数改成10000000了,你那个方法要2s多,这个600多ms
JiinYuu 2012-12-12
  • 打赏
  • 举报
回复
能改bytes的来源的方法么,把他的返回值改为char[]; 如果不能改,你每次取bytes里面的位数都确定么,每次都是最后两个么?
aotian16 2012-12-12
  • 打赏
  • 举报
回复
是比较长的, = =!!!
JiinYuu 2012-12-12
  • 打赏
  • 举报
回复
引用 6 楼 aotian16 的回复:
引用 5 楼 yUu_lean 的回复:StringBuilder sb = new StringBuilder(); long start = System.currentTimeMillis(); char[] bytes = {1,2,3,4}; for (int i = 0; i < 100000; i++) { sb.append(bytes, 2,……
如果bytes长度不多,可以复制下;如果很长,可能就得不偿失了。
aotian16 2012-12-12
  • 打赏
  • 举报
回复
引用 5 楼 yUu_lean 的回复:
StringBuilder sb = new StringBuilder(); long start = System.currentTimeMillis(); char[] bytes = {1,2,3,4}; for (int i = 0; i < 100000; i++) { sb.append(bytes, 2, 2); } long end = ……
这个好啊, 可惜我取到的值已经是byte数组了 难道我自己复制下?
JiinYuu 2012-12-12
  • 打赏
  • 举报
回复
StringBuilder sb = new StringBuilder(); long start = System.currentTimeMillis(); char[] bytes = {1,2,3,4}; for (int i = 0; i < 100000; i++) { sb.append(bytes, 2, 2); } long end = System.currentTimeMillis(); System.out.println(end - start); 只要5ms int是可以直接当做char的
aotian16 2012-12-12
  • 打赏
  • 举报
回复
1楼的我试过了, 没有什么效果 2楼的, 问题是byte数组不是固定的, 也就是string也是变化的
faping_cao 2012-12-12
  • 打赏
  • 举报
回复
String string = new String(bytes, 2, 2); 放在for外面, 还是说bytes每次不一样?
linao 2012-12-12
  • 打赏
  • 举报
回复
创建String对象放在for循环外,append 100000次就可以了
  • 打赏
  • 举报
回复
StringBuilder sb = new StringBuilder();
		 
        long start = System.currentTimeMillis();
        byte[] bytes = {1,2,3,4};
        String string=null;
        for (int i = 0; i < 100000; i++) {
            string = new String(bytes, 2, 2);
            sb.append(string);
        }
        long end = System.currentTimeMillis();
 
        System.out.println(end - start);
  • 打赏
  • 举报
回复
/** * @param sb * @param bytes */ private static long foo3(StringBuilder sb, byte[] bytes) { long start = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { char[] chars = new char[40]; for (int j = 0; j < chars.length; j++) { chars[j] = (char) bytes[j + 2]; } sb.append(chars); } long end = System.currentTimeMillis(); return end - start; } 如果byte[]是由中文字符串获取的,将byte直接转换为char是错误的做法, private static String foo( byte[] bytes) { int time = 100000; int size = 0; byte[] buff = new byte[time<<2]; for (int i = 0; i < time; i++) { int contentSize = bytes.length-2; if(buff.length-size<contentSize){ int tmpLength = buff.length; while(tmpLength-size<contentSize){ tmpLength=tmpLength<<1; } byte[] tmp = new byte[tmpLength]; System.arraycopy(buff,0,tmp,0,size); buff=tmp; } System.arraycopy(bytes, 2, buff, size, contentSize); size +=contentSize; } String result = new String(buff,0,size); return result; }
aotian16 2012-12-12
  • 打赏
  • 举报
回复
貌似还是复制最快了, 大家帮我试试
package pkg;

public class TestBytes {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		StringBuilder sb = new StringBuilder();

		byte[] bytes = {1, 2,
				97, 98, 97, 98, 97, 98, 97, 98, 97, 98, 
				97, 98, 97, 98, 97, 98, 97, 98, 97, 98, 
				97, 98, 97, 98, 97, 98, 97, 98, 97, 98, 
				97, 98, 97, 98, 97, 98, 97, 98, 97, 98,};

		System.out.print(foo1(sb, bytes));
		sb.delete(0, sb.length());
		System.out.print(",");
		System.out.print(foo2(sb, bytes));
		sb.delete(0, sb.length());
		System.out.print(",");
		System.out.print(foo3(sb, bytes));
		sb.delete(0, sb.length());
		System.out.print(",");
		System.out.print(foo4(sb, bytes));
		sb.delete(0, sb.length());
		System.out.println();

	}

	/**
	 * @param sb
	 * @param bytes
	 */
	private static long foo4(StringBuilder sb, byte[] bytes) {
		long start = System.currentTimeMillis();

		for (int i = 0; i < 100000; i++) {
			for (int j = 0; j < bytes.length - 2; j++) {
				sb.append(bytes[j + 2]);
			}

		}
		long end = System.currentTimeMillis();

		return end - start;
	}

	/**
	 * @param sb
	 * @param bytes
	 */
	private static long foo3(StringBuilder sb, byte[] bytes) {
		long start = System.currentTimeMillis();

		for (int i = 0; i < 100000; i++) {
			char[] chars = new char[40];
			for (int j = 0; j < chars.length; j++) {
				chars[j] = (char) bytes[j + 2];
			}
			sb.append(chars);

		}
		long end = System.currentTimeMillis();

		return end - start;
	}

	/**
	 * @param sb
	 * @param bytes
	 */
	private static long foo2(StringBuilder sb, byte[] bytes) {
		long start = System.currentTimeMillis();

		String string = null;
		for (int i = 0; i < 100000; i++) {
			string = new String(bytes, 2, 40);
			sb.append(string);

		}
		long end = System.currentTimeMillis();

		return end - start;
	}

	/**
	 * @param sb
	 * @param bytes
	 */
	private static long foo1(StringBuilder sb, byte[] bytes) {
		long start = System.currentTimeMillis();
		String string = "abababababababababababababababababababab";
		for (int i = 0; i < 100000; i++) {
			sb.append(string);

		}
		long end = System.currentTimeMillis();

		return end - start;
	}

}
结果为 62,110,15,140

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧