Возможно ли как-то ускорить и асинхронизировать эту функцию?

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 шт):

Автор решения: AnnaBazueva

Немного ускорить можно используя 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 пользователей;
  • код значимых узлов кода Вашего бота;
  • и др. аспекты.
→ Ссылка
Автор решения: eri

Для вызова этого кода с асинхронщиной нужен ProcessPoolExecutor. объявите его глобально и выставляйте лимит на количество процессов сопоставимый с количеством ядер компьютера.

Для того чтоб файлы не перезаписывались используйте временные каталоги через mkdtemp. перейдите в этот каталог перед запуском pdflatex. выйдите из него и удалите вместе с файлами после получения результата.

Временный каталог создавайте внутри процесса из ProcessPoolExecutor.

у меня команда выполняется 0.6+0.05 секунды, правда на i5-4430 а не core2duo. но всеже 20 секунд - это на томик войны и мира. похоже у Вас железо на грани смерти.

→ Ссылка