python / python/cpython

Slow inspect.getmodule

Aberta
#92,041 3 comentários 15 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

3.12 performance stdlib type-bug
Linguagem predominante
Python
Estrelas
77.2k
Forks
36k
Métricas de merge de PRs
Métricas de PR pendentes

Descrição

Bug report

inspect.getmodule is slow. It becomes slower as len(sys.modules) grows. It is slower with modules that don't resolve to valid file paths. This causes inspect.stack and others to be slow as well.

def run_test(module):
    # cols have stack depths
    # rows have len(sys.modules)

    def print_line(h, *vals):
        if not h:
            print("%5s" % h, *["%6i" % v for v in vals])
        else:
            print("%5s" % h, *["%6.1f" % v for v in vals])

    def add_modules(n):
        import random
        import sys
        for _ in range(n):
            sys.modules[f"foo_{random.randint(0,2**64)}"] = module

    def measure(depth):
        import inspect
        import timeit

        def nest(level):
            if level > 0:
                return nest(level-1)
            else:
                dur = timeit.timeit(lambda: inspect.stack(), number=1)
                return dur * 1000

        return nest(depth)

    import sys
    print_line("", *[2**e for e in range(7)])
    for i in range(1, 5):
        add_modules(n=10**i)
        times = [measure(depth=2**e) for e in range(7)]
        print_line(len(sys.modules), *times)

python 3.11.0a7+ optimized build ====

# sys has no __file__ and doesn't enter getmodule cache
>>> import sys
>>> run_test(sys)
           1      2      4      8     16     32     64
   87    2.1    0.8    1.0    1.3    2.0    3.3    6.1
  187    2.0    2.5    2.7    3.6    5.5    9.5   16.8
 1187   13.6   15.7   19.1   26.3   39.6   67.4  123.3
11187  134.1  150.3  183.4  252.0  383.5  750.3 1189.8
>>> exit()

>>> import random
>>> run_test(random)
           1      2      4      8     16     32     64
   87    2.1    0.7    0.9    1.2    1.7    2.9    5.6
  187    2.3    1.1    1.5    1.8    2.5    4.3    7.8
 1187   17.0    4.3    5.6    7.1   11.1   18.6   33.9
11187  164.6   37.4   45.7   61.6   94.7  161.0  297.7
>>> exit()

Tables show time in milliseconds for a single inspect.stack() call.
Rows show len(sys.modules)
Columns indicate stack depth

Your environment

  • CPython versions tested on: 3.9, 3.11.0a7+
  • Operating system and architecture: MacOS, Linux, x64
  • PR: gh-92042
  • PR: gh-154403
  • PR: gh-156685

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece lendo as implementações de inspect.getmodule e inspect.stack e, em seguida, reproduza o benchmark fornecido com tamanhos crescentes de sys.modules e profundidades de pilha cada vez maiores. Revise os PRs referenciados gh-92042, gh-154403 e gh-156685 antes de fazer alterações; considera-se concluído quando o problema de escalabilidade relatado estiver resolvido e o benchmark ou os testes relevantes mostrarem a melhoria.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
python
Domínio
tooling
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Estagnada
Clareza
Precisa de esclarecimento
Facilidade para iniciantes
20/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.