2017-12-30 14 views
4

Ich werde über Nützlichkeit fragen. Es geht um die Auswirkung auf die Größe der kompilierten ausführbaren Datei/Bibliothek. Nicht über die Wartbarkeit oder Lesbarkeit des Codes.Können explizite Importe kompilierte Dateigröße reduzieren?

Importieren spezifische Modul

ist es nützlich, die nur verwendet Modul aus einem Paket zu importieren, anstatt das Hauptmodul des Importierens (die selbst die Submodule Importe).

Zum Beispiel mit dem Foreign Modul (die nur eine Importliste enthält):

import Foreign.Storable 

statt:

import Foreign 

Explizit Import Funktionen/Typen

Ist es sinnvoll, nur die verwendeten Funktionen/Typen importieren, anstatt das ganze Modul zu importieren?

Zum Beispiel:

import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtr, withForeignPtr) 

statt:

import Foreign.ForeignPtr 
+5

Haben Sie versucht, eine einfache Anwendung auf zwei verschiedene Arten zu kompilieren und zu sehen, ob Sie einen Unterschied bekommen? Mein Verdacht ist, dass Sie größere Dateien erhalten, wenn Sie ohne Optimierung und die gleiche Größe mit Optimierung kompilieren. Aber vielleicht brauchen Sie LTO. Ich glaube nicht, dass Sie einen Unterschied beim Importieren von Funktionen im Vergleich zu einem Modul gleichzeitig bekommen werden –

+2

Dies ist kein Merkmal des Haskell-Codes; Es ist eine Eigenschaft der Verknüpfung.Erstens, wenn Sie dynamisch verknüpfen, wird nichts davon einen Unterschied machen, also nehme ich an, dass Sie über statische Verknüpfungen sprechen. Im ersten Fall hat es nur einen Effekt, wenn ['split-objs'] (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/phases.html#ghc-flag--split -objs) ist aktiviert; Andernfalls ist die gesamte Bibliothek verknüpft. Im zweiten Fall wird es niemals einen Unterschied machen; Das Importieren von sogar keinen Namen (!) von einem Modul erfordert das Verknüpfen des gesamten Moduls (oder des gesamten Pakets ohne aktivierte "split-objs"). – user2407038

+0

@ user2407038 Danke für Ihre Antwort! Machen Sie es zu einer richtigen Antwort und ich werde es bestätigen. –

Antwort

1

Wenn die Module als Objektdatei kompiliert werden, dann nein, nicht einmal in der Theorie. Funktionen, die nicht importiert werden können, können weiterhin intern verwendet werden, und Sie können das Modul unter GHCI laden und die nicht exportierten internen Funktionen testen.

Wenn Sie statisch verknüpfen oder bestimmte Instanzen einer generischen Funktion verwenden, sollte der Compiler theoretisch in der Lage sein, zu analysieren, welche Teile der Bibliothek von diesem spezifischen Programm nicht erreichbar sind, und als ganze Programmoptimierung sie aus der ausführbaren Datei. (Zum Beispiel, wenn die einzigen Listen, die Ihr Programm verwendet, Listen von Int sind, kompiliert der Compiler möglicherweise nur die teilweise spezialisierten [Int] Versionen von generischen Funktionen und nur die, die Sie verwenden.) Es sollte jedoch in der Lage sein, die gleiche statische zu tun Analyse als Ganzes - Programmoptimierung, egal wie Sie Ihre Importe und Exporte deklarieren.

Beim Kompilieren einer dynamischen Bibliothek könnte theoretisch ein Codepfad oder ein Teil der Daten ausgeschlossen werden, den die statische Analyse niemals direkt oder indirekt durch einen möglichen Aufruf über die exportierte Schnittstelle erreichen kann. Wenn dies der Fall ist, könnte ein Compiler die Exportliste verwenden, um zu beweisen, dass ein Bezeichner in der Bibliothek völlig unbrauchbar ist, und ihn aus der kompilierten Bibliothek herauslassen.

Wenn Sie fragen, was ein bestimmter Compiler, wie GHC 8, tut, weiß ich nicht. Du müsstest es testen und sehen.

Der Hauptvorteil der gezielten Auflistung Ihrer Exporte und Importe besteht darin, dass Sie Jahre später nie Probleme bekommen, wenn ein zweites Modul einen bereits verwendeten Bezeichner deklariert. Das ist mir schon einmal passiert, und jetzt bin ich viel vorsichtiger.

Verwandte Themen