Ich habe Code in nativem C ++ (Visual C ++ 2010), um eine Datei von einigen GB zu verarbeiten. Ich habe es in eine .exe kompiliert und es dauert ungefähr 8 Minuten. Aber ich muss es von einer Visual Basic .net-Schnittstelle aufrufen, also habe ich es in eine .dll-Datei geschrieben und eine C ++ / CLI-Wrapper-Klasse erstellt, um meinen Code in einer nativen DLL aufzurufen. Die einzige Interaktion zwischen dem verwalteten Code und der nativen DLL besteht darin, die Funktion aufzurufen, die die Verarbeitung initiiert. Zu meiner Überraschung dauert die Verarbeitung fast doppelt so lange wie die EXE-Zeit. Ich bin nicht wirklich ein Experte in VB.net, also vielleicht gibt es einige Einstellungen oder etwas zu sehen, weiß ich nicht. Jede Idee willkommen. Vielen Dank im Voraus.
Ideenpaare:
Vielleicht haben Sie die .exe mit der Release-Konfiguration erstellt, aber die .dll wurde auf Debug gesetzt. Sie sehen manchmal einen großen Unterschied zwischen Release- und Debug-Builds, optimierter Code macht einen großen Unterschied.
Wenn Ihr VB.net irgendetwas anderes tut, als den C ++ - Code aufzurufen, dann könnte es CPU-Last hinzufügen, zusätzlich zu dem, was Ihre .dll verbraucht. Jede Art von Hintergrundverarbeitung, die auf der VB.net-Seite durchgeführt wird, könnte für den Unterschied verantwortlich sein. Um Äpfel mit Äpfeln zu vergleichen, sollten Sie eine VB.net-App-Befehlszeile ohne GUI und mit einer einzelnen Zeile, die die DLL-Funktion aufruft, verwenden.
Wenn das obige nicht hilft, empfehle ich Ihnen, eine native C ++ - Anwendung zu erstellen, die mit derselben DLL verknüpft und diese mit der nativen exe-Version vergleicht. Wenn die C ++ - und DLL-Version dasselbe wie die C ++ - Standalone-EXE durchführt, dann muss es etwas auf der VB.net-Seite geben, das zusätzliche CPU verbraucht. Wenn auf der anderen Seite die DLL auch langsam ist, wenn sie von nativem C ++ aufgerufen wird, dann sollten Sie nach Unterschieden in Ihrem Build-Prozess für exe vs. dll oder nach Unterschieden in Makros / bedingten Kompilationen für exe vs. dll-Modus suchen. p>
Viel Glück.
Ruft der C ++ / CLI-Wrapper wirklich nur die DLL-Funktion auf, oder lädt er die DLL selbst, bleibt dann stehen und wird von .NET verwaltet? Erhält die native Prozedur einen eigenen Thread oder einen im Kontext von .NET erstellten Thread? Mein Vorteil ist, dass .NET etwas unnötig macht, um die Lebensdauer des Objekts, der DLL oder des Threads zu verwalten.
Ich schlage daher vor, ein Ereignis hinzuzufügen, um anzuzeigen, dass die DLL mit dem fertig ist, was sie gerade tut, einen neuen Thread aus der nativen DLL zu starten, um die Prozedur auszuführen, und die Ereigniskennung sofort zurückzugeben. Lassen Sie Ihr .NET dort warten, wo es angebracht ist.
Nicht wirklich verstehen, warum die native DLL, die von der DotNet-Seite aufgerufen wird, die Verarbeitungszeit verdoppeln kann, wenn Sie nicht mehr Details angeben können.
Wenn die native exe-Version jedoch wie erwartet funktioniert, können Sie die native exe als Hintergrundprozess von DotNet aus ausführen und die API-Parameter über die Befehlszeile übergeben. Sie können die Konsolenausgabe der exe sogar auf die DotNet-basierte GUI umleiten.
Das ist seltsam. Ich untersuche alle im Taskmanager vorhandenen Spalten und vergleiche die beiden Prozesse (Arbeitssatzgröße, Seitenfehler, ...). Dann schaute ich mir den Performance Monitor an und untersuchte die Werte des Cache-Managers. Last but not least können Sie versuchen, nur aus Dateien zu lesen und nicht zu schreiben, um zu sehen, wo die Zeit verbracht wird.
Das .NET-Framework verursacht einen gewissen Overhead bei der Kommunikation von seinem "verwalteten" Code zu nativem oder "nicht verwaltetem" Code. Hier finden Sie Hintergrundinformationen.
Was Sie in Bezug auf die Leistung sehen, ist das, was ich allgemein erwarte. Wenn die native DLL mehr Arbeit verrichten würde, würde ich erwarten, dass der Kommunikationsaufwand (Effizienzstrafe) geringer ist.