¿Declaración de variables detrás del bucle o dentro del bucle? - página 10

 
Vict:

tiempo = 1018
suma = 894782460
tiempo = 371
suma = 894782460

No sé por qué, pero µl lo supera (y las variantes más intrincadas de rand() también).

Y para mí es obvio: sacarlo del bucle.

Sí, tienes razón, yo también lo probé en VS y por alguna razón no optimizaba nada, aunque parece una variante tan sencilla... De hecho se reduce a esto:

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

Sí, tienes razón, lo he probado también en VS - por alguna razón no está optimizado en lo más mínimo, aunque una opción tan simple, parece... En esencia se reduce a esto:

¿Estás seguro de que has activado toda la optimización en la configuración del proyecto? En casos extraños conecto la generación del listado de ensamblaje y lo reviso, es muy instructivo.

 

Decidí probarlo también en C# por curiosidad. No sólo los resultados son casi iguales en velocidad, sino que también funcionan mucho más rápido que en 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:

Suma: 894782460, Tiempo: 69 ms.

Suma: 894782460, Tiempo: 56 ms

Y aquí hay un análogo en C++:

Suma: 894782460, Tiempo: 2947 ms

Suma: 894782460, Tiempo: 684 ms

Lo pruebo en VS 2019,toda la optimización está habilitada .

Que se joda tal C++).

p.s. Los resultados en C# varían gratamente de una prueba a otra, pero en promedio ambas variantes son igualmente rápidas.

 
Alexey Navoykov

Primero hay que entender las razones de los frenos. He investigado un poco, y todo está en línea excepto la llamada

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

que se encuentra en libstdc++. Es decir, en el fondo del bucle casi desnudo el cuello de botella son las propias llamadas a la función (y hay un par de llamadas de ...replaceEmmPKcm también). El compilador puede optimizar dentro de una sola unidad de traducción. Puede intentar utilizar LTO (link time optimization), es decir, esto permite optimizar en la fase de enlace. Pero no lo he usado, no lo haré ahora. Bueno, no hay nada particularmente complicado - pasar al compilador/linker la opción -flto (pero me falta algún plugin), demasiado perezoso para averiguarlo + puede que tenga que reconstruir libstdc++.

¿Cómo será la optimización del código en relación con el próximo atornillado de módulos (desde C++20)? No sé, puedes probar en vs, aunque todo es crudo y experimentalhttps://habr.com/en/company/pvs-studio/blog/328482/

c++'u se echará de menos )).

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

Por interés, decidí hacer la prueba también en C#. Los resultados no sólo son casi iguales en términos de velocidad, sino que además funcionan un orden de magnitud más rápido que en C++.

Resultados:

Suma: 894782460, Tiempo: 69 ms

Suma: 894782460, Tiempo: 56 ms

Y aquí hay un análogo en C++:

Suma: 894782460, Tiempo: 2947 ms.

Suma: 894782460, Tiempo: 684 ms

Lo pruebo en VS 2019,toda la optimización está habilitada .

Que se joda tal C++).

p.s. Los resultados en C# fluctúan significativamente de una prueba a otra, pero en promedio ambas variantes son iguales en velocidad.

¡Br-r-r-r, no puede ser! Sharp siempre gana a los profesionales puros por un factor de dos, pon el proyecto plz.

 

Niños pequeños :)

Han estirado el juguete a 10 páginas...

 
Vict:

Aquí debemos entender las razones de la lentitud al principio. He investigado un poco y todo está en línea excepto la llamada

que se encuentra en libstdc++.

Así que parece que se ha dado cuenta de que asigna y borra memoria cada vez incluso en este caso:

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


Por cierto, puede que haya dado resultados erróneos la última vez. Lo más probable es que fuera en modo x86. Ahora estoy probando en modo x64 y los resultados por C++ son mucho mejores:

1) ~ 2000 mseg.

2) ~ 200 ms (es 3 veces más rápido).

Aunque también actualicé Studio a la última versión, debe haber influido también ya que incluso x86 es más rápido ahora que las pruebas anteriores.

Bueno, ahora C++ no está tan vergonzosamente por detrás de Sharp. Sólo por 3 veces aproximadamente )

 
Alexey Navoykov:

Así que parece que se ha dado cuenta de que asigna y borra memoria cada vez incluso en este caso:


Por cierto, puede que haya dado resultados erróneos la última vez. Lo más probable es que fuera en modo x86. Ahora estoy probando en modo x64 y los resultados por C++ son mucho mejores:

1) ~ 2000 mseg.

2) ~ 200 ms (es 3 veces más rápido).

Aunque también actualicé Studio a la última versión, debe haber influido también ya que incluso x86 es más rápido ahora que las pruebas anteriores.

Bueno, ahora C++ no pierde tan vergonzosamente contra Sharp. Sólo por 3 veces aproximadamente )

no entiendes, no es lo que quiero decir. En general, la prueba es un juguete: un bucle desnudo sin carga útil. Traté de decirle que las pérdidas en las llamadas de función, que no puede obtener en línea. Mejor prueba más módulos, resultados más interesantes allí, aunque puede ser todavía sin desarrollar.
 
Alexey Volchanskiy:

Brrr-r-rr, ¡no puede ser! Sharp siempre ha sido el doble de bueno que clean pluses, pon el proyecto plz.

Archivos adjuntos:
Project1.zip  1671 kb
 
Vict:
Mejor prueba los módulos plus, los resultados son más interesantes allí, aunque todavía pueden estar indocumentados.

Lo he buscado, resulta que ningún compilador de https://en.cppreference.com/w/cpp/compiler_support ha terminado los módulos, así que no hay nada que ver.

Razón de la queja: