Declarando variáveis atrás do laço ou dentro do laço? - página 10

 
Vict:

tempo = 1018
soma = 894782460
tempo = 371
soma = 894782460

Não sei por que, mas µl o ultrapassa (e também variantes rand() mais intrincadas).

E para mim é óbvio - tire-o do laço.

Sim, você está certo, eu também experimentei em VS e por alguma razão não otimizou em nada, embora uma variante tão simples pareça... Na verdade, se resume a isto:

char *st = new char[23];
memcpy(st, "12345678qwertyuioasdfgh", 23);
sum += st[i % 23];
delete[] st;
 
Alexey Navoykov:

Sim, você está certo, eu também já tentei em VS - por alguma razão não está otimizado no mínimo, embora uma opção tão simples, parece... Em essência, tudo se resume a isto:

Você tem certeza de ter ativado toda a otimização em configurações do projeto? Em casos estranhos, eu ligo a geração de listagem de montagem e olho através dela, é muito instrutiva.

 

Decidi testá-lo em C# também por curiosidade. Não só os resultados são quase os mesmos em velocidade, mas também funcionam muito mais rápido que C++.

public class Program
{
  public static void Main()
    {
        int count = (int)10 e6;

        {
            var watch = System.Diagnostics.Stopwatch.StartNew();
            int sum = 0;
            for (int i = 0; i < count; i++)
            {
                string st;
                st = "12345678qwertyuioasdfgh";
                sum += st[i % 23];
            }
            Console.WriteLine("Sum: {0}, Time: {1} ms", sum, watch.ElapsedMilliseconds);
        }

        {
            var watch = System.Diagnostics.Stopwatch.StartNew();
            int sum = 0;
            string st;
            for (int i = 0; i < count; i++)
            {
                st = "12345678qwertyuioasdfgh";
                sum += st[i % 23];
            }
            Console.WriteLine("Sum: {0}, Time: {1} ms", sum, watch.ElapsedMilliseconds);
        }

        Console.ReadKey();
    }
}

Resultados:

Soma: 894782460, Tempo: 69 ms.

Soma: 894782460, Tempo: 56 ms

E aqui está um análogo em C++:

Soma: 894782460, Tempo: 2947 ms

Soma: 894782460, Tempo: 684 ms

Testei-o no VS 2019.Toda otimização está habilitada .

Parafusar um C++).

p.s. Os resultados em C# variam agradavelmente de teste para teste, mas na média, ambas as variantes são igualmente rápidas.

 
Alexey Navoykov

Você precisa entender primeiro as razões para os freios. Fiz uma pequena escavação, e tudo está em linha, exceto a chamada

0x41a727 <main()+119>   callq  0x48e1a0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEmmPKcm>

que se encontra na libstdc+++. Ou seja, no fundo do loop quase nu, o gargalo é a função chamada a si mesmo (e há um par de chamadas de ...substituirEmmPKcm também). O compilador pode otimizar dentro de uma única unidade de tradução. Você pode tentar usar o LTO (link time optimization), ou seja, isto permite otimizar na etapa de ligação. Mas eu não o usei, não o farei agora. Bem, não há nada particularmente complicado - passe para a opção compiler/linker -flto (mas falta algum plugin), preguiçoso demais para perceber + pode ter que reconstruir a libstdc++.

Como será com a otimização do código em conexão com os próximos módulos de aparafusamento (desde C++20) ? Eu não sei, você pode tentar em vs, embora tudo esteja cru e experimentalhttps://habr.com/en/company/pvs-studio/blog/328482/

c++'u não será atendido )).

Использование модулей C++ в Visual Studio 2017
Использование модулей C++ в Visual Studio 2017
  • habr.com
Команда Visual C++ рада сообщить, что в Visual Studio 2017 было существенно улучшено качество реализации модулей C++ согласно технической спецификации; также мы добавили возможность подключать Стандартную Библиотеку C++ через интерфейсы модулей. Эти интерфейсы, как и поддержка модулей компилятором, являются экспериментальной разработкой и будут...
 
Alexey Navoykov:

Por interesse, decidi testar também em C#. Não só os resultados são quase os mesmos em termos de velocidade, mas também trabalham uma ordem de grandeza mais rápida do que C++.

Resultados:

Soma: 894782460, Tempo: 69 ms

Soma: 894782460, Tempo: 56 ms

E aqui está um análogo em C++:

Soma: 894782460, Tempo: 2947 ms.

Soma: 894782460, Tempo: 684 ms

Testei-o no VS 2019.Toda otimização está habilitada .

Parafusar um C++).

p.s. Os resultados em C# flutuam significativamente de teste para teste, mas na média ambas as variantes são iguais em velocidade.

Br-r-r-r-r, nem pensar! O Sharp sempre venceu os profissionais puros por um fator de dois, você coloca o projeto para fora do plz.

 

Crianças pequenas :)

Eles esticaram o brinquedo para 10 páginas...

 
Vict:

Aqui devemos entender as razões da lentidão no início. Eu fiz uma pequena escavação e tudo está em linha, exceto a chamada

que se encontra na libstdc+++.

Portanto, parece ter descoberto que ele aloca e elimina a memória toda vez que mesmo neste caso:

char *str = new char[23];
...
delete str;


A propósito, posso ter dado resultados errados da última vez. O mais provável foi no modo x86. Agora estou testando no modo x64 e os resultados por C++ são muito melhores:

1) ~ 2000 msec

2) ~ 200 ms (é 3 vezes mais rápido).

Embora eu também tenha atualizado o Studio para a versão mais recente, ele também deve ter influenciado, já que até o x86 é mais rápido agora do que os testes anteriores.

Bem, agora o C++ não está tão vergonhosamente atrasado em Sharp. Apenas por 3 vezes aproximadamente )

 
Alexey Navoykov:

Portanto, parece ter descoberto que ele aloca e elimina a memória toda vez que mesmo neste caso:


A propósito, posso ter dado resultados errados da última vez. O mais provável foi no modo x86. Agora estou testando no modo x64 e os resultados por C++ são muito melhores:

1) ~ 2000 msec

2) ~ 200 ms (é 3 vezes mais rápido).

Embora eu também tenha atualizado o Studio para a versão mais recente, ele também deve ter influenciado, já que até o x86 é mais rápido agora do que os testes anteriores.

Bem, agora C++ não está perdendo tão vergonhosamente para Sharp. Apenas por 3 vezes aproximadamente )

você não entende, não é isso que eu quero dizer. Em geral, o teste é um brinquedo - um loop nu, sem carga útil. Eu estava tentando lhe dizer que as perdas em chamadas de função que não podem entrar em linha. Melhores módulos de teste mais, resultados mais interessantes lá, embora ainda possam estar por desenvolver.
 
Alexey Volchanskiy:

Brrr-r-rr, de jeito nenhum! Sharp sempre foi duas vezes melhor do que plz limpo, você coloca o projeto para fora do plz.

Arquivos anexados:
Project1.zip  1671 kb
 
Vict:
Melhor testar os módulos plus, os resultados são mais interessantes lá, embora eles ainda possam estar indocumentados.

Eu procurei, e descobri que nenhum compilador https://en.cppreference.com/w/cpp/compiler_support terminou os módulos, então não há nada para ver.