Skip to content

Instantly share code, notes, and snippets.

@levic
Forked from djfroofy/performance_results.txt
Last active March 22, 2023 04:03
Show Gist options
  • Save levic/fbcac9ea3974d2cbdfb187c7e655f2e5 to your computer and use it in GitHub Desktop.
Save levic/fbcac9ea3974d2cbdfb187c7e655f2e5 to your computer and use it in GitHub Desktop.
Lists vs. StringIO vs. Regular String Concat for building strings in Python
=================================
Python 3.11
=================================
Concatenating 5 strings...
build_ul_list : 1.0
build_ul_stringio : 1.629
build_ul_concat : 1.013
Concatenating 32 strings...
build_ul_list : 1.0
build_ul_stringio : 1.356
build_ul_concat : 1.074
Concatenating 302 strings...
build_ul_list : 1.0
build_ul_stringio : 1.253
build_ul_concat : 1.375
Concatenating 3,002 strings...
build_ul_list : 1.0
build_ul_stringio : 1.296
build_ul_concat : 1.398
Concatenating 30,002 strings...
build_ul_list : 1.0
build_ul_stringio : 1.23
build_ul_concat : 1.567
Concatenating 300,002 strings...
build_ul_list : 1.0
build_ul_stringio : 1.296
build_ul_concat : 1.615
Concatenating 3,000,002 strings...
build_ul_list : 1.0
build_ul_stringio : 1.22
build_ul_concat : 1.6
Results are pretty noisy as each test only runs for ~1.5sec; use as a rough guide only
=================================
Python 3.6
=================================
Concatenating 5 strings...
build_ul_list : 1.0
build_ul_stringio : 1.702
build_ul_concat : 1.045
Concatenating 32 strings...
build_ul_list : 1.0
build_ul_stringio : 1.342
build_ul_concat : 1.021
Concatenating 302 strings...
build_ul_list : 1.0
build_ul_stringio : 1.215
build_ul_concat : 1.257
Concatenating 3,002 strings...
build_ul_list : 1.0
build_ul_stringio : 1.237
build_ul_concat : 1.48
Concatenating 30,002 strings...
build_ul_list : 1.0
build_ul_stringio : 1.255
build_ul_concat : 1.672
Concatenating 300,002 strings...
build_ul_list : 1.0
build_ul_stringio : 1.015
build_ul_concat : 1.141
Concatenating 3,000,002 strings...
build_ul_list : 1.0
build_ul_stringio : 1.333
build_ul_concat : 1.811
#!/usr/bin/env python3
from io import StringIO
from itertools import permutations
import string
import random
import sys
import timeit
word = 'x' * 8
words = [''.join(p) for p in permutations(string.ascii_letters[:8])]
def get_8x():
return word
next_word = -1
def get_random_word():
global next_word
next_word += 1
next_word %= len(words)
return words[next_word]
#return random.choice(words)
def build_ul_list(linect, get_word=get_8x):
buffer = ['<ul>\n']
for i in range(linect):
buffer.extend([
'<li>', get_word(), '</li>',
])
buffer.append('</ul>')
return ''.join(buffer)
def build_ul_stringio(linect, get_word=get_8x):
buffer = StringIO()
buffer.write('<ul>\n')
for i in range(linect):
buffer.write('<li>')
buffer.write(get_word())
buffer.write('</li>')
buffer.write('</ul>')
return buffer.getvalue()
def build_ul_concat(linect, get_word=get_8x):
buffer = '<ul>\n'
for i in range(linect):
buffer += '<li>'
buffer += get_word()
buffer += '</li>'
buffer += '</ul>'
def run_tests(size, iter_count):
string_count = 2 + 3 * size
print(f"Concatenating {string_count:,} strings", end="", flush=True)
fastest = None
results = {}
for fn in (build_ul_list, build_ul_stringio, build_ul_concat):
elapsed = timeit.timeit(lambda: fn(size, get_word=get_random_word), number=iter_count)
if fastest is None or fastest > elapsed:
fastest = elapsed
results[fn] = elapsed
print(".", end="", flush=True)
print()
for fn, elapsed in results.items():
print(f"{fn.__name__:20}: {elapsed/fastest:.4}")
if __name__ == "__main__":
print("=================================")
print(f"Python {'.'.join(str(x) for x in sys.version_info[:2])}")
print("=================================")
run_tests(1, 5000000)
run_tests(10, 500000)
run_tests(100, 50000)
run_tests(1000, 5000)
run_tests(10000, 500)
run_tests(100000, 50)
run_tests(1000000, 5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment