Простой ответ - всякий раз, когда ваш SQL не изменяет данные, и у вас есть запрос, который может мешать другим действиям (через блокировку).
Стоит рассмотреть любые запросы, используемые для отчетов, особенно если запрос занимает больше, чем, скажем, 1 секунду.
Это особенно полезно, если у вас есть отчеты типа OLAP, которые вы используете против базы данных OLTP.
Первый вопрос, который нужно задать, хотя , «почему я беспокоюсь об этом?» По моему опыту, мошенничество по умолчанию блокировки часто происходит, когда кто-то находится в режиме «попробуй что-нибудь», и это один случай, когда неожиданные последствия маловероятны. Слишком часто это случай преждевременной оптимизации и может быть слишком легко вставлен в приложение «на всякий случай». Важно понять, почему вы это делаете, какую проблему он решает, и есть ли у вас проблема.
Это O (1) (постоянное время, не зависящее от фактической длины элемента - очень быстро) для каждого типа, о котором вы упоминали, плюс set
и других, таких как array.array
.
Нижеследующие измерения свидетельствуют о том, что len()
является O (1) для часто используемых структур данных.
Замечание относительно timeit
: Когда используется флаг -s
и две строки переданы на timeit
, первая строка выполняется только один раз и не синхронизирована.
$ python -m timeit -s "l = range(10);" "len(l)"
10000000 loops, best of 3: 0.0677 usec per loop
$ python -m timeit -s "l = range(1000000);" "len(l)"
10000000 loops, best of 3: 0.0688 usec per loop
$ python -m timeit -s "t = (1,)*10;" "len(t)"
10000000 loops, best of 3: 0.0712 usec per loop
$ python -m timeit -s "t = (1,)*1000000;" "len(t)"
10000000 loops, best of 3: 0.0699 usec per loop
$ python -m timeit -s "s = '1'*10;" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop
$ python -m timeit -s "s = '1'*1000000;" "len(s)"
10000000 loops, best of 3: 0.0686 usec per loop
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(10))};" "len(d)"
10000000 loops, best of 3: 0.0711 usec per loop
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(1000000))};" "len(d)"
10000000 loops, best of 3: 0.0727 usec per loop
$ python -mtimeit -s"import array;a=array.array('i',range(10));" "len(a)"
10000000 loops, best of 3: 0.0682 usec per loop
$ python -mtimeit -s"import array;a=array.array('i',range(1000000));" "len(a)"
10000000 loops, best of 3: 0.0753 usec per loop
$ python -mtimeit -s"s = {i for i in range(10)};" "len(s)"
10000000 loops, best of 3: 0.0754 usec per loop
$ python -mtimeit -s"s = {i for i in range(1000000)};" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop
$ python -mtimeit -s"from collections import deque;d=deque(range(10));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop
$ python -mtimeit -s"from collections import deque;d=deque(range(1000000));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop
Вызов len () для этих типов данных - O (1) в CPython , наиболее распространенная реализация языка Python. Вот ссылка на таблицу, которая обеспечивает алгоритмическую сложность многих различных функций в CPython:
Все эти объекты отслеживают свою длину. Время для извлечения длины невелико (O (1) в примечании большой O) и в основном состоит из [грубого описания, написанного на терминах Python, а не терминов C]: найдите «len» в словаре и отправьте его на built_in len, которая будет искать метод __len__
объекта и вызывает это ... все, что ему нужно сделать, это return self.length