Created
February 25, 2019 17:58
-
-
Save peterbe/b2b7ed95d422ab25a65639cb8412e75e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from django.core.wsgi import get_wsgi_application | |
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "songsearch.settings") | |
application = get_wsgi_application() | |
from songsearch.main.models import * | |
import hashlib | |
def f1(a): | |
names = [] | |
for song in Song.objects.filter(artist=a): | |
names.append(song.name) | |
return hashlib.md5("".join(names).encode("utf-8")).hexdigest() | |
def f2(a): | |
names = [] | |
for song in Song.objects.filter(artist=a).only("name"): | |
names.append(song.name) | |
return hashlib.md5("".join(names).encode("utf-8")).hexdigest() | |
def f3(a): | |
names = [] | |
for song in Song.objects.filter(artist=a).values("name"): | |
names.append(song["name"]) | |
return hashlib.md5("".join(names).encode("utf-8")).hexdigest() | |
def f4(a): | |
names = [] | |
for name in Song.objects.filter(artist=a).values_list("name", flat=True): | |
names.append(name) | |
return hashlib.md5("".join(names).encode("utf-8")).hexdigest() | |
from django.contrib.postgres.aggregates import StringAgg | |
from django.db.models import Func | |
def f5(a): | |
# https://www.peterbe.com/plog/django-orm-optimization-story-on-selecting-the-least-possible#c5043c8 | |
return Song.objects.filter(artist=a).aggregate( | |
names_hash=Func(StringAgg("name", ""), function="md5") | |
) | |
def f6(a): | |
# https://www.peterbe.com/plog/django-orm-optimization-story-on-selecting-the-least-possible#c5043c8 | |
return hashlib.md5( | |
Song.objects.filter(artist=a) | |
.aggregate(names_hash=StringAgg("name", ""))["names_hash"] | |
.encode("utf-8") | |
).hexdigest() | |
artist = Artist.objects.get(name="Bad Religion") | |
print(Song.objects.filter(artist=artist).count()) | |
print(f1(artist) == f2(artist)) | |
print(f2(artist) == f3(artist)) | |
print(f3(artist) == f4(artist)) | |
print(f4(artist) == f5(artist)) | |
print(f5(artist) == f6(artist)) | |
# Reporting | |
import time | |
import random | |
import statistics | |
functions = f1, f2, f3, f4, f5, f6 | |
times = {f.__name__: [] for f in functions} | |
for i in range(500): | |
func = random.choice(functions) | |
t0 = time.time() | |
func(artist) | |
t1 = time.time() | |
times[func.__name__].append((t1 - t0) * 1000) | |
for name in sorted(times): | |
numbers = times[name] | |
print("FUNCTION:", name, "Used", len(numbers), "times") | |
print("\tBEST", min(numbers)) | |
print("\tMEDIAN", statistics.median(numbers)) | |
print("\tMEAN ", statistics.mean(numbers)) | |
print("\tSTDEV ", statistics.stdev(numbers)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output I get as of Feb 25 2019: