字符串相加并不慢
2011 10 19 11:17 PM 3430次查看
			分类:编程 标签:Python, 性能, JavaScript, Java
这个偏见影响了我几年,直到今天才发现它并不一定适用于其他语言。
先来看看Java的版本:
public class Test {
	private static void f() {
		long d = System.currentTimeMillis();
		for (int i = 0; i < 100; ++i) {
			String s = "";
			for (int j = 0; j < 1000; ++j) {
				s += "1234567890";
			}
		}
		System.out.println(System.currentTimeMillis() - d);
	}
	private static void g() {
		long d = System.currentTimeMillis();
		for (int i = 0; i < 10000; ++i) {
			StringBuilder sb = new StringBuilder();
			for (int j = 0; j < 1000; ++j) {
				sb.append("1234567890");
			}
			String s = sb.toString();
		}
		System.out.println(System.currentTimeMillis() - d);
	}
	public static void main(String[] args) {
		f();
		g();
	}
}注意因为String相加太慢,所以循环的执行次数只有StringBuilder的1%。最终测试结果分别是610和640,可见StringBuilder要快2个数量级。
接着看看JavaScript(在Chrome上运行):
function f() {
	var d = new Date();
	for (var i = 0; i < 10000; ++i) {
		var s = '';
		for (var j = 0; j < 1000; ++j) {
			s += '1234567890';
		}
	}
	console.log(new Date() - d);
}
function g() {
	var d = new Date();
	for (var i = 0; i < 10000; ++i) {
		var a = [];
		for (var j = 0; j < 1000; ++j) {
			a.push('1234567890');
		}
		var s = a.join();
	}
	console.log(new Date() - d);
}
f();
g();结果分别是147和203,字符串相加逆转了。值得一提的是,速度居然比Java还快。最后看Python:
from timeit import Timer
from io import BytesIO
def f():
	s = ''
	for i in xrange(1000):
		s += '1234567890'
def g():
	a = []
	for i in xrange(1000):
		a.append('1234567890')
	s = ''.join(a)
def h():
	b = BytesIO()
	for i in xrange(1000):
		b.write('1234567890')
	s = b.getvalue()
print Timer('f()', 'from __main__ import f').timeit(10000)
print Timer('g()', 'from __main__ import g').timeit(10000)
print Timer('h()', 'from __main__ import h').timeit(10000)成绩分别是2.17029650416、2.00979007108和2.48308178833,字符串略慢于数组,但快于BytesIO。不得不说这个测试结果让我凌乱了,难道是Java的String太笨重了么?
向下滚动可载入更多评论,或者点这里禁止自动加载。