!python --version
Python 2.7.6
loop_count = 100
def method1():
out_str = ''
for num in xrange(loop_count):
out_str += `num`
return out_str
# backticks: int -> str
`10`
'10'
str(10)
'10'
method1()
'0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899'
%timeit?
%timeit method1()
1000000 loops, best of 3: 1.25 µs per loop
%timeit -n 1000 -r 10 method1()
1000 loops, best of 10: 9.94 µs per loop
%timeit -n 1000 -r 10 -p 3 -o method1()
1000 loops, best of 10: 10.1 µs per loop
<TimeitResult : 1000 loops, best of 10: 10.1 µs per loop>
%timeit -n 1000 method1()
1000 loops, best of 3: 10.1 µs per loop
%%timeit?
def method2():
from UserString import MutableString
out_str = MutableString()
for num in xrange(loop_count):
out_str += `num`
return out_str
c의 array로 만들고
fromstring으로 string으로 가져와서 배열의 끝에 추가한다.
마지막으로 tostring() 해서 string으로 만든다.
Arryas are mutable in python. 그래서 원래 있던 문자열은 복사하지 않는다.
def method3():
from array import array
char_array = array('c')
for num in xrange(loop_count):
char_array.fromstring(`num`)
return char_array.tostring()
method3()
'012345678910111213141516171819'
from array import array
char_array = array('c')
char_array
array('c')
char_array.fromstring(`5`)
char_array
array('c', '5')
char_array.fromstring(`6`)
char_array
array('c', '56')
char_array.tostring()
'56'
def method4():
str_list = []
for num in xrange(loop_count):
str_list.append(`num`)
out_str = ''.join(str_list)
return out_str
l = []
ll = l.append
ll(1)
ll
<function append>
ll(10)
l
[1, 10]
def method4_2():
str_list = []
str_list2 = str_list.append
for num in xrange(loop_count):
str_list2(`num`)
out_str = ''.join(str_list)
return out_str
def method5():
from cStringIO import StringIO
file_str = StringIO()
for num in xrange(loop_count):
file_str.write(`num`)
out_str = file_str.getvalue()
return out_str
def method6():
out_str = ''.join([`num` for num in xrange(loop_count)])
return out_str
# generator로 생성
def method7():
out_str = ''.join((`num` for num in xrange(loop_count)))
return out_str
loop_count = 20000
%timeit method1()
100 loops, best of 3: 2.58 ms per loop
%timeit method2()
%timeit method3()
100 loops, best of 3: 6.45 ms per loop
%timeit method4()
100 loops, best of 3: 2.84 ms per loop
# 확실히 빨라졌다!
%timeit method4_2()
100 loops, best of 3: 2.07 ms per loop
%timeit method5()
100 loops, best of 3: 7.66 ms per loop
%timeit method6()
1000 loops, best of 3: 1.76 ms per loop
%timeit method7()
100 loops, best of 3: 2.1 ms per loop
밀리초(ms) : 1/1,000초
마이크로초(μs) : 1/1,000,000초
나노초(ns) : 1/1,000,000,000초
피코초(ps) : 1/1,000,000,000,000초
펨토초(fs) : 1/1,000,000,000,000,000초
아토초(as) : 1/1,000,000,000,000,000,000초
ms : 밀리초 0.001 = 10^(-3)초
㎲ : 마이크로초 0.000001초 = 10^(-6)초
㎱: 나노초 0.000000001초 = 10^(-9)초
㎰ : 피코초 0.000000000001초 = 10^(-12)초
fs : 펨토초 0.000000000000001초 = 10^(-15)초
as : 아토초 0.000000000000000001초 = 10^(-18)초
1024byte = 1KB (kilo byte)
1024KB = 1MB (mega byte)
1024MB = 1GB (giga byte) = 1048576 KB
1024GB = 1TB (tela byte)
1024TB = 1PB (peta byte)
timeit: 100, 1000 loops 이든 어짜피 best 3의 결과만 보면 된다.
loop_count = 500000
%timeit method1()
10 loops, best of 3: 84.7 ms per loop
%timeit method2()
%timeit method3()
1 loops, best of 3: 178 ms per loop
%timeit method4()
10 loops, best of 3: 90 ms per loop
%timeit method5()
1 loops, best of 3: 197 ms per loop
%timeit method6()
10 loops, best of 3: 62.8 ms per loop
import time
def check_time(func):
def inner(*args, **kwargs):
start = time.time()
for i in range(10):
ret = func(*args, **kwargs)
end = time.time()
print '%.8f' % (end - start)
return ret
return inner
@check_time
def method1():
out_str = ''
for num in xrange(loop_count):
out_str += `num`
# return out_str
@check_time
def method3():
from array import array
char_array = array('c')
for num in xrange(loop_count):
char_array.fromstring(`num`)
char_array.tostring()
@check_time
def method4():
str_list = []
for num in xrange(loop_count):
str_list.append(`num`)
''.join(str_list)
@check_time
def method5():
from cStringIO import StringIO
file_str = StringIO()
for num in xrange(loop_count):
file_str.write(`num`)
file_str.getvalue()
@check_time
def method6():
''.join([`num` for num in xrange(loop_count)])
method1()
0.87336206
method3()
1.85140491
method4()
0.94222403
method5()
2.01019597
method6()
0.66609311
%%writefile tmp/original_str_performance.py
from cStringIO import StringIO
import time, commands, os
from sys import argv
def method1():
out_str = ''
for num in xrange(loop_count):
out_str += `num`
ps_stats()
return out_str
def method2():
from UserString import MutableString
out_str = MutableString()
for num in xrange(loop_count):
out_str += `num`
ps_stats()
return out_str
def method3():
from array import array
char_array = array('c')
for num in xrange(loop_count):
char_array.fromstring(`num`)
ps_stats()
return char_array.tostring()
def method4():
str_list = []
for num in xrange(loop_count):
str_list.append(`num`)
out_str = ''.join(str_list)
ps_stats()
return out_str
def method4_2():
str_list = []
str_list2 = str_list.append
for num in xrange(loop_count):
str_list2(`num`)
out_str = ''.join(str_list)
ps_stats()
return out_str
def method5():
file_str = StringIO()
for num in xrange(loop_count):
file_str.write(`num`)
out_str = file_str.getvalue()
ps_stats()
return out_str
def method6():
out_str = ''.join([`num` for num in xrange(loop_count)])
ps_stats()
return out_str
def ps_stats():
global process_size
ps = commands.getoutput('ps -l ' + `pid`)
process_size = ps.split()[23]
def call_method(num):
global process_size
start = time.time()
z = eval('method' + str(num))()
end = time.time()
print "method", num
print "time", float(end-start) * 100
print "output size ", len(z) / 1024, "kb"
print "process size", process_size, "kb"
print
loop_count = 100000
pid = os.getpid()
if len(argv) == 2:
call_method(argv[1])
else:
print "Usage: python stest.py <n>\n" \
" where n is the method number to test"
Overwriting tmp/original_str_performance.py
!python tmp/original_str_performance.py 1
method 1 time 2.25088596344 output size 477 kb process size 4616 kb
%run tmp/original_str_performance.py 1
method 1 time 2.80869007111 output size 477 kb process size 59764 kb
%run tmp/original_str_performance.py 2
method 2 time 185.649013519 output size 477 kb process size 59452 kb
%run tmp/original_str_performance.py 3
method 3 time 4.83219623566 output size 477 kb process size 58760 kb
!python tmp/original_str_performance.py 4
method 4 time 2.69351005554 output size 477 kb process size 10336 kb
%run tmp/original_str_performance.py 4_2
method 4_2 time 2.11400985718 output size 477 kb process size 62208 kb
%run tmp/original_str_performance.py 5
method 5 time 5.35268783569 output size 477 kb process size 59916 kb
%run tmp/original_str_performance.py 6
method 6 time 1.88450813293 output size 477 kb process size 59892 kb