In Django does .get() have better performance than .first()? - django

The Django implementation of .first() seems to get all items into a list and then return the first one.
Is .get() more performant ? Surely the database can just return one item, the implementation of .first() seems suboptimal,

I see no reason to think so, although I have not actually profiled.
Slicing on Django querysets is implemented by modifying the query to use LIMIT and OFFSET terms to retrieve only the necessary number of elements. This means the first() implementation only fetches a single element from the database.

Related

In Django, why does queryset's iterator() method reduce memory usage?

In Django, I can't understand why queryset's iterator() method reduces memory usage.
Django document says like below.
A QuerySet typically caches its results internally so that repeated evaluations do not result in additional queries. In contrast, iterator() will read results directly, without doing any caching at the QuerySet level (internally, the default iterator calls iterator() and caches the return value). For a QuerySet which returns a large number of objects that you only need to access once, this can result in better performance and a significant reduction in memory.
In my knowledge, however, wheather iterator() method is used or not, after evaluation, the queried rows are fetched from the database at once and loaded into memory. Isn't it the same that memory proportional to the number of rows is used, wheather the queryset do caching or not? Then what is the benifit of using iterator() method, assuming evaluating the queryset only once?
Is it because raw data fetched from the database and data that is cached (after instantiating) are stored in separate memory spaces? If so, I think I can understand that not performing caching using the iterator() method saves memory.
When using iterator, Django uses DB cursors to get data row by row. If you use something like all and iterate on that with python, all of the records would be cached in the memory while you need one by one.
So by using iterator, you are using DB cursor, and fetching data one by one, and the other records would not be fetched all at once.

QAbstractItemModel - Should QModelIndex objects be cached when created?

When subclassing a QAbstractItemModel and re-implementing the index() method, I had been simply returning a new index each time with createIndex(). But I noticed that the index() method gets called thousands of times when the model is used in conjunction with a view, for all sorts of paint events and whatnot.
Should I instead be caching the QModelIndex object after I generate it the first time in index(), and then be returning the cached index when index() is subsequently called on the same row/col? It's not mentioned in the documentation, and it seems that indexes themselves can become invalidated under certain circumstances, so I am unsure of what to do here.
In my particular case, I'm working with Pyside6, but I imaging this could apply to any implementation of the Qt framework.
If your model supports inserting or removing rows, your indexes are not persistent. You can still use cache but you must invalidate it every time model shape changes.
If creating index logic is complicated there might be benefit in caching.
Size of QModelIndex is about four ints (row, column and pointer/id and pointer), so it's relatively lightweight, creating and moving it around is cheap.
Either way there's only one way to be sure: try caching and measure perfomance gain.

Does iterator provide improvement when used together with values_list?

Recently I saw code which used together iterator() and values_list(). Does it make sence to use them both together? Will it improve speed or memory usage?
Sample code:
Customer.objects.values_list("pk", flat=True).iterator()
value_list() returns a QuerySet that returns dictionaries[docs].
QuerySets are lazy – the act of creating a QuerySet doesn’t involve any database activity. You can stack filters together all day long, and Django won’t actually run the query until the QuerySet is evaluated [docs].
You can see this to check when a queryset is evaluated.
In fact by creating a queryset django doesn't hit the database until it is being evaluated (by something like iterator).
as Iterator() read the results without caching will result to better performance in situations we need to access the objects just onece, and it's not related to the kind of querysets

populate a list once

Using datomic and clojure I query a database and get a list of nine elements.
I would like to draw these nine elements on the page, and at this point they are guaranteed to be distinct elements.
However, every time I call the function, it redoes the query, returns a new list, and then gets an element from the new list. This is very inefficient and also introduces the possibility of duplicates.
I would like to memoize this list and have it be nth-indexable. Suggestions and ideas welcome.
Instead of calling "the function", you should only call it if you have not called it already. If you call it, make sure to store the result. If you don't call it, look up the result.
memoize (http://crossclj.info/fun/clojure.core/memoize.html) might help you to achieve that. Depending on your cache requirements, you might want to study its implementation and implement something more suitable.
You might want to refer to https://github.com/clojure/core.memoize for more sophisticated memoization needs on the serverside.
Any list is nth-indexable with O(n). For O(log 32 n) performance, create a vector from it using vec.

Django queryset reversing ways

I know two ways to reverse ordered queryset:
qs.objects.filter(**cond).order_by('-field_name')
and
qs.objects.filter(**cond).order_by('field_name').reverse()
Is there any appropriate case (except of tempates) to use second way?
I don't believe there is an appropriate case, from what I understand qs.objects.filter(**cond).order_by('-field_name') is done at the database level, so it will outperform calling reverse on the queryset.