webapp: speed up encode_and_buffer
authorHelmut Grohne <helmut@subdivi.de>
Wed, 29 Dec 2021 20:00:04 +0000 (21:00 +0100)
committerHelmut Grohne <helmut@subdivi.de>
Wed, 29 Dec 2021 20:00:04 +0000 (21:00 +0100)
We now know that our parameter is a jinja2.environment.TemplateStream.
Enable buffering and accumulate via an io.BytesIO to avoid O(n^2)
append.

webapp.py

index 9993cb0..d91d724 100755 (executable)
--- a/webapp.py
+++ b/webapp.py
@@ -3,6 +3,7 @@
 import argparse
 import contextlib
 import datetime
+import io
 import sqlite3
 from wsgiref.simple_server import make_server
 
@@ -49,15 +50,16 @@ hash_template = jinjaenv.get_template("hash.html")
 index_template = jinjaenv.get_template("index.html")
 source_template = jinjaenv.get_template("source.html")
 
-def encode_and_buffer(iterator):
-    buff = b""
-    for elem in iterator:
-        buff += elem.encode("utf8")
-        if len(buff) >= 2048:
-            yield buff
-            buff = b""
-    if buff:
-        yield buff
+def encode_and_buffer(stream):
+    stream.enable_buffering(16)
+    buff = io.BytesIO()
+    for elem in stream:
+        buff.write(elem.encode("utf8"))
+        if buff.tell() >= 2048:
+            yield buff.getvalue()
+            buff = io.BytesIO()
+    if buff.tell() > 0:
+        yield buff.getvalue()
 
 def html_response(unicode_iterator, max_age=24 * 60 * 60):
     resp = Response(encode_and_buffer(unicode_iterator), mimetype="text/html")