It is slower but not 60x slower in this system
TL; DR; Use write('\n'.join(...)) instead of writelines(...)
$ pypy -m timeit -s "path='tst'" "with file(path, 'w') as f:f.writelines(['testing to write a file\n' for i in range(5000000)])" 10 loops, best of 3: 1.15 sec per loop $ python -m timeit -s "path='tst'" "with file(path, 'w') as f:f.writelines(['testing to write a file\n' for i in range(5000000)])" 10 loops, best of 3: 434 msec per loop
xrange doesn't matter
$ pypy -m timeit -s "path='tst'" "with file(path, 'w') as f:f.writelines(['testing to write a file\n' for i in xrange(5000000)])" 10 loops, best of 3: 1.15 sec per loop
Using a generator expression is slower for pypy but faster for python
$ pypy -m timeit -s "path='tst'" "with file(path, 'w') as f:f.writelines('testing to write a file\n' for i in xrange(5000000))" 10 loops, best of 3: 1.62 sec per loop $ python -m timeit -s "path='tst'" "with file(path, 'w') as f:f.writelines('testing to write a file\n' for i in xrange(5000000))" 10 loops, best of 3: 407 msec per loop
moving data creation outside of the reference amplifies the difference (~ 4.2x)
$ pypy -m timeit -s "path='tst'; data=['testing to write a file\n' for i in range(5000000)]" "with file(path, 'w') as f:f.writelines(data)" 10 loops, best of 3: 786 msec per loop $ python -m timeit -s "path='tst'; data=['testing to write a file\n' for i in range(5000000)]" "with file(path, 'w') as f:f.writelines(data)" 10 loops, best of 3: 189 msec per loop
Using write() instead of writelines() much faster for both
$ pypy -m timeit -s "path='tst'; data='\n'.join('testing to write a file\n' for i in range(5000000))" "with file(path, 'w') as f:f.write(data)" 10 loops, best of 3: 51.9 msec per loop $ python -m timeit -s "path='tst'; data='\n'.join('testing to write a file\n' for i in range(5000000))" "with file(path, 'w') as f:f.write(data)" 10 loops, best of 3: 52.4 msec per loop
$ uname -srvmpio Linux 3.2.0-26-generic