Quero executar uma variante da correspondência de bloqueio de fonte ancorada. Eu tenho definições de função que começam com uma lista de nomes e quero que esses nomes sejam destacados dentro do corpo da função.
Eu criei uma função que faz isso e a registrei como uma função jit-lock com jit-lock-register, no entanto, o desempenho é muito ruim e a rolagem fica lenta em arquivos maiores.
- Como posso medir o desempenho? Se eu apenas chamar minha função em um arquivo grande (com tempo de flutuação antes e depois ou com elp), obtém um desempenho bastante variado, leva de 0,65 a 12 segundos. Existe uma maneira recomendada de comparar o desempenho do bloqueio de fonte?
- Existe alguma diferença no desempenho entre um comparador ancorado definido em palavras-chave de bloqueio de fonte e a adição de uma função via jit-lock-register?
Edit: Parece que a variabilidade no desempenho está relacionada à coleta de lixo, as invocações da minha função jit-lock ficam sucessivamente mais lentas a cada invocação até que a coleta de lixo seja executada, e nesse ponto elas ficam mais rápidas novamente.
font-lock
performance
Joakim Hårsman
fonte
fonte
Respostas:
Acontece que o desempenho bastante variado estava relacionado à coleta de lixo. Cada chamada para a função ficaria mais lenta até que uma coleta de lixo fosse executada. Com o estoque emacs, o gc era executado a cada dois segundos, mas eu tinha uma linha no init.el para melhorar o tempo de inicialização que definia o limite de gc-cons-20 para 20 MB, e isso significava que o gc era executado com muito menos frequência, fazendo com que os benchmarks relatar um tempo cada vez mais lento até que um gc fosse executado depois de alguns minutos; os tempos despencariam e seriam rápidos novamente.
Após reverter para o padrão gc-cons-threshhold, o benchmarking ficou mais fácil.
Em seguida, criei um perfil de memória com o profiler interno (
M-x profiler-start
) e descobri que as chamadas para syntax-ppss causavam mais alocações; portanto, após alguma otimização para chamar syntax-ppss com menos frequência, obtive um desempenho aceitável.Usar o modo jit-lock (adicionar uma função via jit-lock-register) parece ser a maneira mais fácil de fazer com que o bloqueio de fontes de várias linhas funcione de maneira confiável, e esse foi o método que eu escolhi.
Edit: Depois de descobrir que o desempenho ainda não era bom o suficiente em buffers muito grandes, passei muito tempo otimizando o uso e a alocação da CPU, medindo as melhorias de desempenho com o criador de perfil Emacs (
M-x profiler-start
). No entanto, o Emacs ainda gagueja e trava ao rolar rapidamente por buffers muito grandes. A remoção da função jit-lock com a qual eu me registreijit-lock-register
removeria a gagueira e o travamento, mas o perfil mostrou que a função jit-lock é concluída em cerca de 8 ms, o que deve ser rápido o suficiente para uma rolagem suave. A remoção da chamadajit-lock-register
e, em vez disso, o uso de um correspondente regular de bloqueio de fonte-palavras-chave resolveu o problema.TLDR: Fazer isso era lento e gaguejava:
Fazer isso era rápido e não gaguejava:
fonte
dyalog-fontify-locals
.dyalog-fontify-locals-matcher
deveria sermy-font-lock-matcher
e um dosend
deveria serlimit
. Enfim, descoberta realmente interessante!gc-cons-threshold
Se você estiver mexendo com valores internos apenas para melhorar o tempo de inicialização, sugiro que você osemacs-startup-hook
restaure posteriormente.