Python по умолчанию кеширует числа int в диапазоне -5...256.
Думаю, это всем известный факт.
Вот вам подсказка, в интерактивной консоли это можно повторить, запустив обе команды как одну.
А оптимизация замечает нашу "бездарную писанину" и исправляет явные ошибки. Грубо говоря, такой код:
Если выполнять команды по отдельности то оптимизация не сработает, так как это отдельные объекты кода.
Если же это одна команда, введёная в консоль или код загружен из модуля, то интерпретатор увидит это как единый блок. Этап оптимизации изменит исходный код и это сведёт на нет наши исследования, выдав не то что мы ожидаем.
#triks
Думаю, это всем известный факт.
>>> a = 10
>>> b = 10
>>> a is b
True
>>> a = 270
>>> b = 270
>>> a is b
False
Но вот что интересно, это не сработает внутри модуля.# matchtest.py ####
a = 270
b = 270
print(a is b)
# end file ########>>> import matchtest
True
Почему одно и тоже работает по разному? Что за двойные стандарты?Вот вам подсказка, в интерактивной консоли это можно повторить, запустив обе команды как одну.
>>> a = 270; b = 270
>>> a is b
True
А разница в том как интерпретатор получает код, точней какими порциями. Каждую "порцию" он "интерпретирует", попутно оптимизируя логику кода.А оптимизация замечает нашу "бездарную писанину" и исправляет явные ошибки. Грубо говоря, такой код:
a = 270
b = 270
Превращается в нечто такое:a = b = 270
Зачем создавать два одинаковых объекта когда можно создать один объект и две ссылки?Если выполнять команды по отдельности то оптимизация не сработает, так как это отдельные объекты кода.
Если же это одна команда, введёная в консоль или код загружен из модуля, то интерпретатор увидит это как единый блок. Этап оптимизации изменит исходный код и это сведёт на нет наши исследования, выдав не то что мы ожидаем.
#triks
Помните трик с заменой строки в консоли с помощью символа
Что будет если сделать несоклько таких символов? Мы вернёмся на несколько строк выше? Нет, так не сработает.
Как же сделать замену нескольких строк?
Для этого нужна хитрая комбинация символов:
Итого, наша абракадабра значит - подняться на строку вверх и удалть всю строку.
Полный список специальных символов можно найти на этой странице.
Эти функции консоли широко используются. Например модуль colorama использует модификации для изменения цвета текста в консоли.
В демке на видео показана манипуляция тремя строками в консоли. Пишем три строки, удаляем три строки, и тд.
➡️ Код с демонстрацией
#triks
"\r"? Рассказывал в этом посте.Что будет если сделать несоклько таких символов? Мы вернёмся на несколько строк выше? Нет, так не сработает.
Как же сделать замену нескольких строк?
Для этого нужна хитрая комбинация символов:
\x1b[1A\x1b[2K
Что это вообще за магия? Это специальный код для управления курсором консоли.\x1b : экранирующий символ означающий что дальше следует специальный символ. Он же символ ESC[1A : команда "поднять курсор вверх". Есть и другие команды для перемещения курсора в разные стороны.[2K : удалить текущую строку. "2" означает всю строку. Еще есть опции: "0" - от курсора до конца, "1" - от курсора к началу.Итого, наша абракадабра значит - подняться на строку вверх и удалть всю строку.
Полный список специальных символов можно найти на этой странице.
Эти функции консоли широко используются. Например модуль colorama использует модификации для изменения цвета текста в консоли.
В демке на видео показана манипуляция тремя строками в консоли. Пишем три строки, удаляем три строки, и тд.
➡️ Код с демонстрацией
#triks
🔥12
В Linux стандартными средствами можно использовать часть оперативной памяти как диск. Для этого требуется указать тип монтирования
▫️ Скорость работы с таким каталогом выше чем многие SSD и тем более HDD.
▫️ Если у вас очень быстрый SSD на NVMe M.2 то такой способ особо не прибавит вам скорости, но поможет сохранить ресурс SSD когда требуется обрабатывать очень много мелких файлов и оперативка позволяет выделить нужный объем.
▫️ Оперативка это энергозависимая память, поэтому выключении питания все файлы безвозвратно теряются. Такой "non persistent" каталог гарантирует удаление временных файлов.
Я написал небольшой скрипт для условного теста и сравнения скорости копирования файлов между SSD и RAM.
Вот мои результаты:
На моём железе прирост скорости ~2x. Плюс экономия ресурса SSD.
В Windows такой фишки по умолчанию нет, но обязательно найдутся аналогичные решения
#linux #triks
tmpfs в команде mountmount -t tmpfs -o size=5G tmpfs /mnt/ramТеперь путь
/mnt/ram можно использовать как обычный каталог. Для чего это может быть нужно?▫️ Скорость работы с таким каталогом выше чем многие SSD и тем более HDD.
▫️ Если у вас очень быстрый SSD на NVMe M.2 то такой способ особо не прибавит вам скорости, но поможет сохранить ресурс SSD когда требуется обрабатывать очень много мелких файлов и оперативка позволяет выделить нужный объем.
▫️ Оперативка это энергозависимая память, поэтому выключении питания все файлы безвозвратно теряются. Такой "non persistent" каталог гарантирует удаление временных файлов.
Я написал небольшой скрипт для условного теста и сравнения скорости копирования файлов между SSD и RAM.
Вот мои результаты:
Single File Size: 30.0GbСкрипт для теста ↗️
ssd > ssd: 0:00:12.850 / 2.3Gb/s
sdd > ram: 0:00:06.453 / 4.6Gb/s
ram > ram: 0:00:06.995 / 4.3Gb/s
ram > sdd: 0:00:06.217 / 4.8Gb/s
Dir size: 32.7Gb, File count: 11127
ssd > ssd: 0:00:15.063 / 2.2Gb/s
sdd > ram: 0:00:08.486 / 3.9Gb/s
ram > ram: 0:00:08.032 / 4.1Gb/s
ram > sdd: 0:00:07.026 / 4.7Gb/s
На моём железе прирост скорости ~2x. Плюс экономия ресурса SSD.
В Windows такой фишки по умолчанию нет, но обязательно найдутся аналогичные решения
#linux #triks
Gist
Test copy speed with ramdisk on linux
Test copy speed with ramdisk on linux. GitHub Gist: instantly share code, notes, and snippets.
👍9🔥2❤1
Где можно применять моржовый (walrus) оператор? (Py3.8+)
Очевидное назначение моржового оператора - сократить количество кода. Сделать присвоение значения переменной и его использование в одно действие. Чаще всего используется в конструкциях
Можно ли использовать его внутри
Это синтаксис форматирования а не walrus. Чтобы превратить выражение в walrus используем скобки
Получается, что скобки помогут использовать walrus не только с
Пример не самого очевидного присвоения значений переменным
Вызов функции тоже может быть использован как скобки для walrus
Два "моржа"на одном пляже в одной строке
В следующем примере мы экономим не только код но и количество расчётов
Создание списка выполняется последовательно, поэтому можно объявить переменную в первом элементе и использовать в остальных
Более страшный пример с созданием
не делайте так
Экономим один вызов
И ещё пример экономии места в файле и времени CPU
А еще не будет ошибкой синтаксиса если использовать walrus перед
Но, по очевидным причинам, смысла в этом нет 😄
#triks
Очевидное назначение моржового оператора - сократить количество кода. Сделать присвоение значения переменной и его использование в одно действие. Чаще всего используется в конструкциях
if и whileif match := pattern.search(data):
print(match.groups())
while chunk := file.read(1024):
process(chunk)
Можно ли использовать его внутри
f-string?print(f'{x:=10}')
# NameError: name 'x' is not definedЭто синтаксис форматирования а не walrus. Чтобы превратить выражение в walrus используем скобки
print(f'{(x:=15)}')
# '15'
print(x)
# 15Получается, что скобки помогут использовать walrus не только с
if, while, match и тд.Пример не самого очевидного присвоения значений переменным
x = (y := 1, 2)
print(x)
print(y)
# (1, 2)
# 1
Вызов функции тоже может быть использован как скобки для walrus
def get(): return 2
def do_it(x, y): return x + y
x = do_it(y := get(), y+3)
print(x, y)
# 7 2
Два "моржа"
def compute(x): return x*2
def get_value(): return 1
if z := compute(x := get_value()):
print(f"compute({x}) = {z}")
else:
print(f"{x} is not valid value")
# compute(1) = 2
В следующем примере мы экономим не только код но и количество расчётов
list1 = [1, 2, 3, 4, 5]
# без walrus
list2 = [x*2 for x in list1 if x*2 % 15 == 0]
# c walrus
list2 = [(n := x*2) for x in list1 if n % 15 == 0]
Создание списка выполняется последовательно, поэтому можно объявить переменную в первом элементе и использовать в остальных
f = lambda v: v*2
[y := f(1), y**2, y**3]
# [2, 4, 8]
Более страшный пример с созданием
lambda через walrus[y := (f := lambda x, i: x*i)(3, 10), z:=f(y, 20), f(z, 30)]
# [30, 600, 18000]
Экономим один вызов
lower() в простом выраженииis_palindrome = (w := word.lower()) == w[::-1]
И ещё пример экономии места в файле и времени CPU
try:
10 / 0
except Exception as err:
logger.log(message := f"Error, {err}!")
send_report(message)
А еще не будет ошибкой синтаксиса если использовать walrus перед
return. def calculate(a, b):
return result := a * b
Но, по очевидным причинам, смысла в этом нет 😄
#triks
👍16🤯3❤1