O código do Visual Studio consome 13% dos recursos da CPU devido à oscilação do cursor



A edição divertida # 22900 desta semana atraiu atenção especial dos usuários do Github.

Uma descrição detalhada do problema está no repositório do editor de código do Visual Studio Code ( vscode ). O desenvolvedor de código aberto Jo Liss é conhecido como o criador do Broccoli e de outras bibliotecas gratuitas. Na página do projeto, ela percebeu que o Visual Studio Code usa 13% dos recursos de computação do processador, se a janela estiver em foco. Por esse motivo, a energia da bateria do laptop é desperdiçada. Qual poderia ser o motivo de um comportamento tão estranho do programa?

Joe Liss sugeriu que a atividade da CPU está associada à renderização do cursor piscar - o estado do cursor muda duas vezes por segundo, ou seja, a cada 500 ms (2 fps).

Para reproduzir o problema, execute as seguintes etapas:

  1. Feche todas as janelas no código do Visual Studio.
  2. Abra uma nova janela (Arquivo → Nova Janela).
  3. Abra uma nova guia com um arquivo vazio (Arquivo → Nova guia). O cursor está piscando.
  4. No monitor de recursos, você verá um consumo diferente de zero dos recursos de computação (13% em um laptop fraco com OS X, cerca de 5-7% em um poderoso Shell do GNOME com Wayland (Ivy Bridge Graphics)).
  5. Alterne para outra janela do aplicativo (Cmd + Tab). O cursor não está mais visível.
  6. O consumo de CPU do Visual Studio Code é reduzido para quase zero.

Alguém precisa, aqui está a linha do tempo para escrever nas Ferramentas do desenvolvedor: TimelineRawData-20170321T114212.json.zip (veja a captura de tela acima).

Se você aumentar o zoom em um quadro, poderá ver que, apesar da frequência de oscilação de 2 qps, o encadeamento principal trabalha a 60 qps, ou seja, renderiza algo a cada 16 ms.



Se você o aproximar ainda mais, poderá ver o grande trabalho concreto que o cursor processa a 60 quadros / s. Estes são os ciclos periódicos “Atualizar árvore de camadas” / “Pintar” / “Camadas compostas”, ou seja, atualizar a árvore de camadas



O desenvolvedor observa que em outros aplicativos do macOS Sierra 10.12.3, incluindo Chrome e TextEdit, o cursor pisca sem um consumo perceptível da CPU.

Os usuários do editor de código do Visual Studio podem desativar a oscilação do cursor no programa. Nesse caso, o consumo da CPU é reduzido para 0%. Os loops "Atualizar árvore de camadas" / "Pintar" / "Camadas compostas" ainda funcionam, mas apenas a cada 500 ms, não a cada 16 ms.

"editor.cursorBlinking": "solid"

Essa falha engraçada no código do Visual Studio lembra um problema clássico de indicador de freio npm. Na npm 3.5.2, com o indicador de progresso aceso, a operação foi executada aproximadamente 50% mais lenta do que sem o indicador.

 $ rm -r node_modules $ npm set progress=false $ time npm install npm install 19.91s user 2.66s system 71% cpu 31.667 total $ rm -r node_modules $ npm set progress=true $ time npm install npm install 33.26s user 3.19s system 74% cpu 48.733 total 

Qual o motivo


Obviamente, o consumo da CPU quando o cursor pisca tem motivos completamente diferentes do que diminuir a velocidade da npm com um indicador de progresso ativo. Você pode adivinhar os motivos dos problemas com o cursor se observar quase o mesmo bug com a animação de quadro-chave CSS no navegador Chrome. Lá, os desenvolvedores escrevem que, em JavaScript, um cursor trêmulo consome 1,2% dos recursos da CPU, e em CSS, por algum motivo, é 6 vezes mais, ou seja, 7-8%.

O código parece estar correto:

 @keyframes monaco-cursor-blink { 50% { opacity: 0; } 100% { opacity: 1; } } .cursor-blink { animation: monaco-cursor-blink 1s step-start 0s infinite; } 

Mas o problema é que o mecanismo Chromium força essa animação a 60 fps, forçando-a a trabalhar a cada 16 ms.

Portanto, o editor de código do Visual Studio obviamente usa a abordagem mais lógica para implementar a função de cursor oscilante: esta é a função de step com animação de quadro-chave CSS. E esse bug no Chromium ainda não foi completamente corrigido , apesar de durar mais de dois anos. Portanto, o Chrome realiza um ciclo completo de renderização a cada 16 ms, como deve ser de 60 quadros por segundo. Talvez a discussão atual chame a atenção para o bug antigo - e os desenvolvedores finalmente ponham as mãos nele.

Os desenvolvedores do Visual Studio Code admitiram que essa função foi implementada originalmente em JavaScript, mas cerca de um ano atrás eles mudaram para CSS. Na implementação atual, se a janela estiver fora de foco, a animação será desativada e não haverá consumo excessivo de recursos do processador, mas há realmente um problema com a janela ativa. Os desenvolvedores acreditam que, em tal situação, faz sentido retornar do CSS para o JS.

Recomenda-se aos colegas que também considerem implementar um cursor como um gif animado. Você pode gerar esse arquivo automaticamente, dependendo do esquema de cores do editor. É verdade que pode haver dificuldade com o zoom: afinal, os gráficos raster ficam embaçados ao aplicar o zoom.

Mas no final, os desenvolvedores da Microsoft ainda decidiram retornar ao bom e velho método JS setInterval para piscar o cursor - e o consumo da CPU imediatamente diminuiu várias vezes .

Source: https://habr.com/ru/post/pt402601/


All Articles