forum: count comments for all presented topics in a single request (#63)

It appears as though performing a lot of requests is the most costly
aspect of listing comment counts per topic; this change aims to address
that by reading all the counts in a single request.

On my computer, this changes loading times from an absolute 100-200 ms to
50-100 ms most of the time. The request impact is not easy to measure as a
couple ms is small enough to fall in the range of disk access and other
semi-random events.
This commit is contained in:
Lephe 2021-07-07 17:26:22 +02:00
parent b00d44ddc1
commit c59e844852
Signed by untrusted user: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
2 changed files with 14 additions and 2 deletions

View File

@ -80,4 +80,16 @@ def forum_page(f, page=1):
topics = f.topics.order_by(Topic.date_created.desc()).paginate(
page, Forum.TOPICS_PER_PAGE, True)
return render('/forum/forum.html', f=f, topics=topics, form=form)
# Count comments; this direct request avoids performing one request for
# each topic.thread.comments.count() in the view, which the database
# doesn't really appreciate performance-wise.
req_comment_counts = \
"SELECT thread_id, COUNT(*) FROM comment WHERE " + \
" OR ".join(f"thread_id={t.thread.id}" for t in topics.items) + \
" GROUP BY thread_id"
comment_counts = db.session.execute(req_comment_counts)
comment_counts = dict(list(comment_counts))
return render('/forum/forum.html', f=f, topics=topics, form=form,
comment_counts=comment_counts)

View File

@ -23,7 +23,7 @@
<tr><td><a href='{{ url_for('forum_topic', f=t.forum, page=(t,1)) }}'>{{ t.title }}</a></td>
<td><a href='{{ url_for('user', username=t.author.name) }}'>{{ t.author.name }}</a></td>
<td>{{ t.date_created | date }}</td>
<td>{{ t.thread.comments.count() }}</td>
<td>{{ comment_counts[t.thread.id] }}</td>
<td>{{ t.views }} </td></tr>
{% endfor %}
</table>