Возможно ли как-то ускорить и асинхронизировать эту функцию?
async def num1():
f=open(".\\seven_minutes-01.tex","w", encoding="utf-8")
# Ответ в t
r=random.randint(0,1)
t2=["BC","CA"][r]
t1=["ABC","CAB"][r]
t3=str(random.randint(10,80))
t=(90-int(t3))*2
tikz=(r"""
\begin{tikzpicture}[line cap=round,line join=round,>=triangle 45,x=1cm,y=1cm]
\draw [line width=1pt] (0,0) circle (2);
\draw [line width=1pt] (0,2)-- (0,-2);
\draw [line width=1pt] (0,2)-- (1.7641506367384823,-0.9422168173489621);
\draw [line width=1pt] (1.7641506367384823,-0.9422168173489621)-- (0,-2);
\draw [fill=black] (0,0) circle (2pt);
\draw [fill=black] (0,2) circle (2pt);
\draw[color=black] (0,2) node[above] {$B$};
\draw [fill=black] (0,-2) circle (2pt);
\draw[color=black] (0,-2) node[below] {$A$};
\draw [fill=black] (1.7641506367384823,-0.9422168173489621) circle (2pt);
\draw[color=black] (1.7641506367384823,-0.9422168173489621) node[right] {$C$};
\draw[color=black] (2,2) node[right] {\begin{tabular}{l} $AB$~--- диаметр\\ $\angle """+ t1+"="+t3+r"""\degr$\\ $\arc """+t2+r"""$~---~?\end{tabular}};
\end{tikzpicture}
""")
expr = (r"""
\documentclass[preview,tikz=true,border=0pt,convert={density=600*600,outext=.png}]{standalone}
\usepackage{tikz,pgfplots}
\usetikzlibrary{arrows}
\usepackage{color}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage[utf8]{inputenc}
\usepackage[T2A]{fontenc}
\usepackage[russian]{babel}
\def\mbb{\mathbb}
\def\-1{^{-1}}
\def\degr{^\circ}
\def\arc{\smallsmile\hspace{-0.7ex}}
\begin{document}""" + tikz +
r"""
\end{document}
""")
f.write(expr)
f.close()
os.system("pdflatex seven_minutes-01.tex && pdftocairo -png seven_minutes-01.pdf -r 1200 -singlefile")
return 'окружности', t, 60
Пишу бота на aiogram, который дает примеры. Занимаюсь геометрией, но возникает трудность: картинка рендерится секунд 20, на макбуке 5. Это очень и долго и может нарушаться асинхронность, т е человек 1 получит пример человека 2. Возможно ли как-то ускорить эту функцию, возможно асинхронизировать? Пока думал только над добавлением aiofiles, но думаю, что ускорится все не сильно.`
Ответы (2 шт):
Немного ускорить можно используя join()
вместо конкатенации строк.
для примера:
start = datetime.now()
for _ in range(10000000):
expr = (r"""
\documentclass[preview,tikz=true,border=0pt,convert={density=600*600,outext=.png}]{standalone}
\usepackage{tikz,pgfplots}
\usetikzlibrary{arrows}
\usepackage{color}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage[utf8]{inputenc}
\usepackage[T2A]{fontenc}
\usepackage[russian]{babel}
\def\mbb{\mathbb}
\def\-1{^{-1}}
\def\degr{^\circ}
\def\arc{\smallsmile\hspace{-0.7ex}}
\begin{document}""" + tikz +
r"""
\end{document}
""")
else:
print(f'Используется "+", время: {datetime.now() - start}')
start = datetime.now()
for _ in range(10000000):
expr = "".join((r"""
\documentclass[preview,tikz=true,border=0pt,convert={density=600*600,outext=.png}]{standalone}
\usepackage{tikz,pgfplots}
\usetikzlibrary{arrows}
\usepackage{color}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage[utf8]{inputenc}
\usepackage[T2A]{fontenc}
\usepackage[russian]{babel}
\def\mbb{\mathbb}
\def\-1{^{-1}}
\def\degr{^\circ}
\def\arc{\smallsmile\hspace{-0.7ex}}
\begin{document}""", tikz,
r"""
\end{document}
"""))
else:
print(f'Используется "join", время: {datetime.now() - start}')
вывод в консоль:
(.venv) PS C:\KWORK> & c:/KWORK/.venv/Scripts/python.exe c:/KWORK/my_test.py
Используется "+", время: 0:00:19.715602
Используется "join", время: 0:00:11.774159
(.venv) PS C:\KWORK>
Что касается проблемы: человек 1 получит пример человека 2
и оптимизации,
этого можно добиться асинхронной реализацией и пересмотром некоторых подходов.
Однако для этого от Вас требуется более подробно описать:
- цели рандомизации задач;
- количество клиентов (пользователе) бота;
- достаточные пределы вариативности задач для
n
пользователей; - код значимых узлов кода Вашего бота;
- и др. аспекты.
Для вызова этого кода с асинхронщиной нужен ProcessPoolExecutor. объявите его глобально и выставляйте лимит на количество процессов сопоставимый с количеством ядер компьютера.
Для того чтоб файлы не перезаписывались используйте временные каталоги через mkdtemp. перейдите в этот каталог перед запуском pdflatex. выйдите из него и удалите вместе с файлами после получения результата.
Временный каталог создавайте внутри процесса из ProcessPoolExecutor.
у меня команда выполняется 0.6+0.05 секунды, правда на i5-4430 а не core2duo. но всеже 20 секунд - это на томик войны и мира. похоже у Вас железо на грани смерти.