Deklarieren von Variablen hinter der Schleife oder innerhalb der Schleife? - Seite 10

 
Vict:

Zeit = 1018
Summe = 894782460
Zeit = 371
Summe = 894782460

Ich weiß nicht, warum, aber µl überholt es (und auch kompliziertere rand()-Varianten).

Und für mich liegt es auf der Hand, sie aus dem Kreislauf herauszunehmen.

Ja, Sie haben Recht, ich versuchte es in VS auch und aus irgendeinem Grund es nicht optimieren überhaupt, obwohl eine solche einfache Variante scheint... In der Tat kommt es auf diese:

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

Ja, Sie haben Recht, ich habe es in VS auch versucht - aus irgendeinem Grund ist es nicht im geringsten optimiert, obwohl so eine einfache Option, es scheinen würde... Im Wesentlichen kommt es auf diese:

Sind Sie sicher, dass Sie alle Optimierungen in den Projekteinstellungen aktiviert haben? In merkwürdigen Fällen schalte ich die Generierung der Baugruppenliste ein und schaue sie mir an, das ist sehr aufschlussreich.

 

Ich habe beschlossen, es aus Neugier auch in C# zu testen, und die Ergebnisse sind nicht nur fast gleich schnell, sondern funktionieren auch viel schneller als in 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();
    }
}

Ergebnisse:

Summe: 894782460, Zeit: 69 ms.

Summe: 894782460, Zeit: 56 ms

Und hier ist ein Analogon in C++:

Summe: 894782460, Zeit: 2947 ms

Summe: 894782460, Zeit: 684 ms

Ich teste es in VS 2019,alle Optimierungen sind aktiviert .

Scheiß auf so ein C++.)

p.s. Die Ergebnisse in C# variieren angenehm von Test zu Test, aber im Durchschnitt sind beide Varianten gleich schnell.

 
Alexey Navoykov

Sie müssen zunächst die Gründe für die Bremsen verstehen. Ich habe ein wenig nachgeforscht, und alles ist inline, außer dem Aufruf

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

die sich in libstdc++ befindet. Das heißt, im Hintergrund der fast nackten Schleife ist der Engpass die Funktionsaufrufe selbst (und es gibt auch ein paar Aufrufe von ...replaceEmmPKcm). Der Compiler kann innerhalb einer einzigen Übersetzungseinheit optimieren. Sie können versuchen, LTO (Link-Time-Optimierung) zu verwenden, d.h. dies ermöglicht eine Optimierung in der Verknüpfungsphase. Aber ich habe es nicht benutzt und werde es auch jetzt nicht tun. Nun, es ist nichts besonders kompliziert - übergeben Sie an Compiler/Linker -flto Option (aber ich habe einige Plugin fehlt), zu faul, um es herauszufinden + möglicherweise libstdc++ neu zu erstellen haben.

Wie sieht es mit der Code-Optimierung in Verbindung mit der kommenden Modulverschraubung (seit C++20) aus? Ich weiß nicht, Sie können es in vs versuchen, aber alles ist roh und experimentellhttps://habr.com/en/company/pvs-studio/blog/328482/

c++'u wird vermisst werden )).

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

Interessehalber habe ich beschlossen, auch in C# zu testen. Die Ergebnisse sind nicht nur in Bezug auf die Geschwindigkeit fast gleich, sondern sie funktionieren auch um eine Größenordnung schneller als in C++.

Ergebnisse:

Summe: 894782460, Zeit: 69 ms

Summe: 894782460, Zeit: 56 ms

Und hier ist ein Analogon in C++:

Summe: 894782460, Zeit: 2947 ms.

Summe: 894782460, Zeit: 684 ms

Ich teste es in VS 2019,alle Optimierungen sind aktiviert .

Scheiß auf so ein C++.)

p.s. Die Ergebnisse in C# schwanken erheblich von Test zu Test, aber im Durchschnitt sind beide Varianten gleich schnell.

Br-r-r-r-r, auf keinen Fall! Sharp hat die reinen Profis immer um den Faktor zwei geschlagen, veröffentlichen Sie das Projekt bitte.

 

Kleine Kinder :)

Sie haben das Spielzeug auf 10 Seiten ausgedehnt...

 
Vict:

Hier sollten wir zunächst die Gründe für die Langsamkeit verstehen. Ich habe ein wenig gegraben und alles ist inline, außer dem Aufruf

die sich in libstdc++ befindet.

Es scheint also herausgefunden zu haben, dass es jedes Mal Speicher zuweist und löscht, auch in diesem Fall:

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


Übrigens kann es sein, dass ich beim letzten Mal falsche Ergebnisse angegeben habe. Wahrscheinlich war es im x86-Modus. Jetzt teste ich im x64-Modus und die Ergebnisse von C++ sind viel besser:

1) ~ 2000 msec

2) ~ 200 ms (das ist 3 Mal schneller).

Obwohl ich auch Studio auf die neueste Version aktualisiert habe, muss sich das auch ausgewirkt haben, denn selbst x86 ist jetzt schneller als bei früheren Tests.

Nun, jetzt liegt C++ nicht mehr so beschämend hinter Sharp zurück (nur etwa um den Faktor 3).

 
Alexey Navoykov:

Es scheint also herausgefunden zu haben, dass es auch in diesem Fall jedes Mal Speicher zuweist und löscht:


Übrigens kann es sein, dass ich beim letzten Mal falsche Ergebnisse angegeben habe. Wahrscheinlich war es im x86-Modus. Jetzt teste ich im x64-Modus und die Ergebnisse von C++ sind viel besser:

1) ~ 2000 msec

2) ~ 200 ms (das ist 3 Mal schneller).

Obwohl ich auch Studio auf die neueste Version aktualisiert habe, muss sich das auch ausgewirkt haben, denn selbst x86 ist jetzt schneller als bei früheren Tests.

Nun, jetzt verliert C++ nicht mehr so schmählich gegen Sharp, sondern nur noch um etwa das Dreifache.)

Du verstehst nicht, das meine ich nicht. Im Allgemeinen ist der Test ein Spielzeug - eine bloße Schleife ohne Nutzlast. Ich habe versucht, Ihnen zu sagen, dass Verluste bei Funktionsaufrufen, die nicht inline werden können. Besserer Test plus Module, interessantere Ergebnisse, auch wenn er noch nicht ganz ausgereift ist.
 
Alexey Volchanskiy:

Brrr-r-rr, das kann nicht sein! Sharp hat immer doppelt so gut wie saubere Pluspunkte, Sie setzen das Projekt aus plz.

Dateien:
Project1.zip  1671 kb
 
Vict:
Testen Sie besser die Plus-Module, dort sind die Ergebnisse interessanter, auch wenn sie vielleicht noch undokumentiert sind.

Ich habe nachgeschaut, es stellt sich heraus, dass kein https://en.cppreference.com/w/cpp/compiler_support Compiler die Module fertiggestellt hat, also gibt es nichts zu sehen.