Difference between revisions of "Size Matters/fr"

From Lazarus wiki
Jump to navigationJump to search
 
(37 intermediate revisions by 2 users not shown)
Line 3: Line 3:
 
= Introduction =
 
= Introduction =
  
This page is about binary sizes. Through the years there has been a lot of confusion about FPC and Lazarus binary sizes. Before you make any remark on the maillist, please read this FAQ.
+
Cette page porte sur les tailles de binaires. Au fil des années il y a eu beaucoup de confusion sur les tailles binaires FPC et Lazarus. Avant de faire des remarques dans les listes de diffusion, SVP, lisez cette FAQ.
  
The main reason for this faq is that most discussions about this subject tend to get caught up in details too quickly. Also the opinion of people that shout "bloat" at nearly everything clouds the global picture often more than it contributes to clarity.  
+
La principale raison pour cette FAQ est que la plupart des discussions sur ce sujet ont tendance à tomber trop rapidement dans les détails. Aussi, l'opinion de gens qui crient "envahit" presque tout et obscurcit l'image globale souvent plus qu'il ne contribue à la clarté.
  
== Rule of thumb, what are current realistic sizes for Free Pascal/Lazarus binaries? ==
+
== Règle générale, que sont les tailles réalistes actuels pour les binaires FPC/Lazarus ? ==
  
* <b>anything under 1MB is not considered a problem</b>.  
+
* <b>Tout ce qui est en dessous de 1 Mo n'est pas un problème</b>.  
** Make sure they are properly <b>stripped and smartlinked</b> before measuring, and that ALL libraries are built using smartlinking.  
+
** Assurez-vous qu'ils sont correctement <b>dépouillés (stripped) et liés intelligemment</b> avant la mesure et que TOUTES les bibliothèques sont construites en utilisant la liaison intelligente.
** <b>DO NOT UPX binaries routinely</b>, unless you have extremely good reasons to do so (see below). The size is less important than the memory load a depacked binary poses. And memory is still more expensive than disc.
+
** <b>NE PAS FAIRE DE binaires UPX par habitude</b>, a moins d'avoir de très bonnes raisons de le faire (voir en dessous). La taille est moins importante que la charge mémoire qu'un binaire décompressé provoque. La mémoire est plus chère que l'espace disque. La plupart des outils d'accès à distance implémente la compression dans leur tunnel.
* With small apps it is a bit harder to estimate. This is because the exact RTL size is OS dependant. However 100k standalone binaries that do something can be done, usually even below 50k.
+
* Avec de petites apps, c'est plus dur à estimer. C'est parce que la taille exacte de la RTL dépend de l'OS. Toutefois, 100ko de binaire autonome qui fait quelque chose peut être fait en général en dessous de 50ko.
** On windows 20k WinAPI GUI using binaries are no problem.
+
** Sous windows 20k d'IHM utilisant des binaires ne sont pas un problème.
** Unit Sysutils contains internationalisation, textual errormessages, and exception handling and some other stuff that is always linked in when this unit is used (think 40-100k total).
+
** L'unité SysUtils contient l'internationalisation, des messages d'erreur en texte, la gestion des exceptions et d'autres trucs qui sont toujours liés quand cette unité est employée (penser à un total de 40-100k).
* Lazarus apps on Windows are about 500k, but quickly grow to 1.5 MB as more and more of the lazarus widgets are used.  
+
* Les apps Lazarus sur Windows font environ 500ko, mais grossissent rapidement à 1,5 Mo et de plus en plus avec les widgets Lazarus utilisés. Les apps binaires Lazarus peuvent passer à plus de 100 Mo quand les infos de débogage sont liées dedans (comparable aux infos TD32 dans Delphi).
** This is a bit more than when recompiling it with a recent delphi, which is the price for cross-platformness and project maintainability.
+
** C'est un peu plus que lorsqu'on recompile avec une ancienne version de Delphi, et un peu moins qu'avec les versions modernes de Delphi (D2009+ la taille minimale de la RTL bondit fortement), c'est le prix de pour la compatibilité croisée de plate-forme et la maintenabilité des projets.
** When the moment is reached where extra code doesn't add a dependancy on more LCL code, this quick growth subsides.  
+
** Quand le moment est atteint l'ajout de code supplémentaire n'introduit pas de nouvelles dépendances, cette croissance rapide disparaît.  
** The 1.5MB point above is a rule-of-thumb. It depends very much on your GUI creation style and the number of different widgets (and their complexity) that you use.
+
** Le point des 1,5Mo du dessus est une règle d'or. Il dépend beaucoup du style de création de votre IHM et du nombre de différents Widgets que vous utilisez et de leur complexité.
** For Lazarus apps quite a percentage of the binary is non-code, mostly strings and tables.
+
** Pour les applications Lazarus, une partie du binaire n'est pas du code, la plupart sont des chaînes et des tables.
* Linux/FreeBSD simple binaries are bigger than the corresponding GCC ones. This is because they don't use shared libraries (which you can easily see using "ldd ./xx")
+
* Les simples binaires Linux/FreeBSD sont plus gros que les GCC correspondants. C'est parce qu'ils n'utilisent pas de bibliothèques partagées (ce que vous pouvez facilement voir <code>ldd ./xx</code>)
* 64-bit binaries will always be larger than x86 ones. In general RISC platforms also generate slightly larger code.
+
* Les binaires 64 bits sont toujours plus gros que leurs équivalents x86. En général, les plates-formes RISC génèrent aussi des binaires légèrement plus gros.
  
== Why are the binaries so big ? ==
+
== Pourquoi les binaires sont si gros ? ==
  
<b>Answer: They are not supposed to be big.</b>
+
<b>Réponse: Ils ne sont pas censés être grand.</b>
  
If you <b>perceive</b> them as big, then
+
Si vous les <b>percevez</b> comme gros, alors
  
* either you didn't configure FPC properly, or
+
* soit vous n'avez pas configuré FPC proprement, ou
* have an unrealistic expectancy of the binary size
+
* vous avez une attente irréaliste de la taille que devrait avoir le binaire
* You are trying to do something that FPC is not designed to do.  
+
* vous essayer de faire quelque chose pour laquelle FPC n'est pas conçu.  
  
The last one is the least likely of all three. I'm going to treat all cases quickly in the next paragraphs.
+
Le dernier est sans le moins probable des trois. Je vais traiter ces trois cas rapidement dans les prochains paragraphes.
  
 +
== Est-ce mauvais quand les binaires sont gros ? ==
  
== Is it bad when binaries are big ? ==
+
Bien, cela dépend de l'ampleur du parcours. Mais il est sûr de dire que presque personne ne devrait être inquiet d'avoir des binaires gros de quelques Mo ou même plus de 10 Mo pour des applications considérables.
  
Well, depends on the magnitude of course. But it is safe to say that hardly anybody should be worried of having binaries as big as a few MB or even over ten MB for sizable applications.
+
Cependant, il y a encore quelques catégories qui pourraient vouloir avoir un certain contrôle sur les fichiers binaires en les gardant petits.
 +
# Le monde de la programmation embarquée évidemment (et alors je ne veux pas dire les PC embarqués qui ont toujours des dizaines de Mo).
 +
# les gens qui distribuent vraiment quotidiennement par modem
 +
# Concours, mesures de performance
  
However, there still are a few categories that might want to have some control over keeping binaries small.
+
Notez qu'une idée fausse souvent citée est celle que des binaires plus gros sont plus lents en fonctionnement. En général, cela n'est pas vrai, 'exotic last-cycle stuff as code cachelines'(non traduit) mis à part.
# the embedded programming world obviously (and then I mean not the embedded PCs which still have tens of MBs)
 
# people that really distribute daily by modem
 
# Contests, benchmarking (the notorious language shootout)
 
  
Note that an often cited misconception is that bigger binaries are slower in operation. In general this is not true, exotic last-cycle stuff as code cachelines aside.  
+
=== Embarqué ===
 +
Alors que Free Pascal est raisonnablement utilisable pour des usages embarqués ou de système, les décisions d'ingénierie de la version finale et de compromis sont basées sur les exigences de construction d'applications plus générales, bien que certaines des cibles les plus intégrées (comme DOS 16 bits ou ARM/AVR/MIPS (= PIC32) étendent cela à la limite.
  
=== Embedded ===
+
Si vous avez des besoins aussi spécialisés pour des objectifs plus réguliers, vous pouvez définir un projet dans l'ombre (quelque chose comme les versions spécialisées de certaines distros Linux qui sont disponibles). Ennuyer l'équipe FPC qui est déjà surchargée avec ces besoins spécifiques n'est pas une option, d'autant plus que la moitié des utilisateurs embarqués sérieux roulent de toutes façons.
  
While Free Pascal is reasonably usable for embedded or system purposes, the final release engineering and tradeoffs are more oriented at general application building. For really specialistic purposes, people could set up a shadow project, more in the way like e.g. there are specialised versions of certain Linux distro's. Worrying the already overburdened FPC team with such specialistic needs is not an option, especially since half of the serious embedded users will roll their own anyway.
+
=== distribution par modem ===
  
=== modem distribution ===
+
Le cas du modem n'est pas seu1ement "télécharger depuis Internet" ou "mon shareware doit être aussi petit que possible", mais p.ex. dans mon ancien travail nous faisions un tas de déploiement vers nos clients et vers nos sites externes via le bureau distant sur le RNIS. Mais même avec un modem 56k, vous ne pouvez pas envoyer 1 Mo en moins de 5 minutes.
  
The modem case is not just about "downloading from the Net" or "my shareware must be as small as possible", but e.g. in my last job we did a lot of deployment to our customers and our own external sites via remote desktop over ISDN. But even with a 56k modem you can squeeze a MB through in under 5 minutes.  
+
Veillez à ne pas abuser de cet argument pour essayer de fournir un fondement rationnel mal placé pour une opinion émotionnelle sur la taille binaire. Si vous faites ce point, cela ne sert à rien sans une analyse statistique approfondie du pourcentage d'utilisateurs de modem réels que vous avez pour votre application (ma plupart des utilisateurs de logiciels ne téléchargent pas depuis Internet mais depuis les CD des magazines de shareware (NdT: ce point de vue n'est plus valbale actuellement).
  
Be careful to not abuse this argument to try to provide a misplaced rational fundament for an emotional opinion about binary size. If you make this point, it is useless without a thorough statistical analysis of what percentage of actual modem users you have for your application (most modem users don't download software from the net, but use e.g. magazine shareware CDs).
+
=== Concours ===
  
=== Contests ===
+
Une autre raison pour garder les binaires petits sont les comparaison de langages (comme le Language Shootout). Cependant ceci est plus comme résoudre un puzzle, et pas vraiment lié au génie logiciel responsable.
  
Another reason to keep binaries small is language comparison contents (like the Language Shootout). However this is more like solving a puzzle, and not really related to responsible software engineering.
+
== Configuration de compilateur incorrecte ==
  
== Incorrect compiler configuration ==
+
Je ne suis pas en train d'expliquer chaque aspect de la configuration du compilateur de manière détaillée, puisque c'est une FAQ, non un manuel. C'est juste un survol. Lire [http://www.freepascal.org/docs.html manuals] et [[buildfaq]] de manière approfondie pour une information plus fondamentale.
  
I'm not going to go explain every aspect of the compiler configuration in great lengths, since this is a FAQ, not the manual. This is meant as an overview only. Read [http://www.freepascal.org/docs.html manuals], and [[buildfaq]] thoroughly for more background info.
+
Il y a généralement plusieurs raisons de pourquoi un binaire semble plus gros qu'attendu.
 +
Cette FAQ couvre les raisons les plus courantes, en ordre décroissant de probabilité:
 +
# le binaire contient encore des informations de débogage.
 +
# le programme n'a pas été (complétement) lié intelligemment.
 +
# Le binaire inclut des unités contenant des sexctions d'initialisation qui execute beaucoup de code.
 +
# vous liez statiquement des biblitohèques externes, plus qu'utilisez des liaisons dynamiques (bibliothèques partagées).
 +
# L'optimisation n'est pas (complètement) activée.
 +
# Le fichier de projet Lazarus (lpr) a des unités de paquet dans sa section uses (c'est fait automatiquement par Lazarus)
  
Generally, there are several reasons why the binary would be bigger than expected.
+
Dans le futur, les liaisons partagées vers une bibliothèque d'exécution FPC et/ou Lazarus devrait changer cette image de manière significative. Bien sûr, cela vous aurez à distribuer une grosse DLL withe pleins d'autres trucs dedans qui vous amènera à des problèmes de versioning).
This FAQ covers the most common reasons, in descending order of likelihood:
 
# The binary still contains debug information.
 
# The binary was not (fully) smartlinked
 
# The binary includes units that have initialisation sections that execute a lot of code.
 
# You link in complete (external) libraries statically, rather than using shared linking.
 
# Optimization is not (entirely) turned on.
 
# Lazarus project file (lpr) has package units in uses section (this is done automagically by lazarus)
 
  
In the future, shared linking to a FPC and/or Lazarus runtime library might significantly alter this picture. Of course then you will have to distribute a big DLL with lots of other stuff in it and the resulting versioning issues. This is all still some time in the future, so it is hard to quantify what the impact on binary sizes would be. Specially because dynamic linking also has size overhead. (on top of unused code in the shared lib)
+
Tout cela est encore dans le futur, il est donc difficile de quantifier l'impact sur les tailles binaires. Surtout parce que la liaison dynamique a également une surcharge de taille (en plus du code inutilisé dans la bibliothèque partagée).
  
=== Debug information ===
+
=== Information de débogage ===
  
Free Pascal uses GDB as debugger and LD as linker. These work with a system of in-binary debuginfo, be it <i>stabs</i> or <i>dwarf</i>. People often see e.g. Lazarus binaries that are 40MB. The correct size should be about 6MB, the rest is debuginfo (and maybe 6 MB from not smartlinking properly).
+
Free Pascal utilise GDB comme débogueur et LD comme éditeur de liens. Ceux-ci travaillent avec des infos de débogage dans le binaire, dans l'ancien format <i>stabs</i> ou le plus récent <i>dwarf</i>. Les gens voient souvent p.ex. des binaires qui font 40 Mo. La bonne taille devrait être autour de 6Mo, le reste sont des informations de débogage (et peut-être 6 Mo pour de la liaison intelligente mal faite).
  
Stabs debuginfo is quite bulky, but has as advantage that it is relatively independant of the binary format. In time it will be replaced on all but the most legacy platforms by DWARF.
+
L'info de débogage Stabs est plutôt encombrante, mais a l'avantage d'être relativement indépendante du format binaire. Elle a été remplacée par DWARF sauf pour certaines plates-formes légataires.
  
There is often confusion with respect to the debuginfo, which is caused by the internal strip in a lot of win32 versions of the binutils. Also some versions of the win32 strip binary don't fully strip the debuginfo generated by FPC. So people toggle some (lazarus/IDE or FPC commandline) flag like -Xs and assume it worked, while it didn't. FPC has been adapted to remedy this, but this will only be in versions from 2006 or later.  
+
Il y a souvent confusion en ce qui concerne les informations de débogage, qui est causée par le strip dans de nombreuses versions win32 des binutils. Aussi certaines versions du binaire Win32 de strip n'élimine pas totalement les infos de débogage générées par FPC. Donc les gens bascule le drapeau tel que -Xs (ligne de commande Lazarus/IDE ou FPC) et suppose que cela marche alors que non. FPC a été adapté pour remédier à cela.
  
So, when in doubt, <b>always</b> try to strip manually, and, on windows, preferably with several different STRIP binaries. Don't drive this too far though, using shoddy binaries of doubtful origin to shave of another byte. Stay with general released (cygwin/mingw and their better beta's) versions.
+
Donc dans le doute, tenter <b>toujours</b> de faire le strip manuellement, et sur Windows, avec plusieurs binaires STRIP différents.
  
In time, when 2.1.1 goes gold, this kind of problems might get rarer on specially Windows, since the internal linker provides a more consistent treatment of these problems. However they may apply to people using non-core targets for quite some time to come.
+
Ce genre de problème devient plus rare particulièrement sur Windows, depuis que l'éditeur de liens interne traite ces problèmes de façon plus consistante. Néanmoins (nez en moins ;-), il s'applique toujours pour les personnes qui utilisent des cibles exotiques pendant un certain temps encore.
  
Keep in mind that the whole strip system is based on shipping the same build as user version (stripped) while retaining the debug version (unstripped) for e.g. interpreting traceback addresses. So if you do formal releases, retain a copy of the unstripped binary that you ship, and always do a release build with debug info
+
Vous pouvez utiliser le système de Strip pour livrer la même construction entre la version allégée (strippée) pour l'utilisateur et conserver la version complète (non strippée) pour p.ex. l'interprétation des adresses de trace arrière. Ainsi, si vous faites des livraisons formelles, conservez toujours une copie complète du binaire que vous enverrez qui sera allégé.
  
The design of GDB itself allows to keep and use debug information out of the binary file (external debug information). That means, the size of resulting binary is not increased due to debug information, and still you can successfully debug the binary. Of cause debug information should be stored somewhere else for GDB. That's why additional .dbg file is created to store the stabs.  You don't need this file to run and use the application, this file is used by debugger only. Since all debug information is moved from the binary file, you will not get much effect if you try to strip it.  
+
La conception de GDB lui-même vous laisse garder et utiliser les informations de débogage en dehors du fichier binaire (infos de débogage externes), dans un fichier séparé .gdb. La taille du binaire résultant n'est pas augmentée du fait des infos de débogage, et vous pouvez toujours réussir à déboguer le binaire. Vous n'avez pas besoin du fichier .dbg pour exécuter l'application, il est utilisé uniquement par le débogueur. Comme les infos de débogage sont externes, il est utile d'utiliser strip.
  
To compile your application in this way, you should use -Xg switch <s>(the option is default for Lazarus 0.9.27 and higher)</s>.  Blank form application for Win32, compiled with external debug information would take about 1 Mb, and .dbg file would take 10 Mb.
+
Pour compiler votre application de cette façon, vous devriez utiliser la bascule -Xg ou l'option correspondante dans l'IHM de Lazarus : dans 'Projet|Options du projet|Options du compilateur|Débogage', laissez 'Generate info for the debugger' active et activez 'Use external debug symbols file'.
  
=== Smartlinking ===
+
[[File:BigExe_FR.png]]
  
''(main article: [[File size and smartlinking]])''
+
Une application avec une fenêtre vide pour Win32, compilée avec des infos de débogage externes doit occuper environ 1 Mo, et le fichier .dbg environ 10 Mo.
  
The base principle of smartlinking is simple and commonly known: don't link in what is not used. This of course has a good effect on binary size.
+
=== Liaison intelligente ===
  
However the compiler is merely a program, and doesn't have a magic crystal ball to see what is used, so the base implementation is more like this
+
''(main article principal: [[File size and smartlinking/fr|File size and smartlinking]])''
* The compiler finely divides the code up in so called "sections".
 
* Then basically the linker determines what sections are used using the rule "if no label in the section is referenced, it can be removed.
 
  
There are some problems with this simplistic view:
+
La principe fondamental de la liaison intelligente est simple et bien connu : ne pas lier ce qui ne sert pas. Ceci a bien sûr un bon effet sur la taille du binaire.
* virtual methods may be implicitely called via their VMTs. The GNU linker can't trace call sequences through these VMTs, so they must all be linked in;
 
* tables for resource strings reference every string constant, and thus all string constants are linked in (one reason for sysutils being big).
 
* symbols that approachable from the outside of the binary (this is possible for non library ELF binaries too) must be kept. This last limitation is necessary to e.g. avoid stripping exported functions from shared libraries..
 
* Another such pain point are published functions and properties. References to published functions/properties can be constructed on the fly using string operations, and the compiler can't trace them. This is one of the downsides of reflection.
 
* Published properties and methods can be resolved by creating the symbolnames using string manipulation, and must therefore be linked in if the class is referenced anywhere. Published code might in turn call private/protected/public code and thus a fairly large inclusion.  
 
  
Another important side effect that is logical, but often forgotten is that this algorithm will link in everything referenced in the initialization and finalization parts of units, even if no functionality from those units are used. So be careful what you USE.
+
Pourtant, le compilateur est seulement un programme et n'a pas une boule de cristal magique pour voir ce qui est utilisé, aussi l'implémentation de base est plutôt comme cela :
 +
* Le compilateur divise le code en soi-disant "sections" qui sont assez petites.
 +
* Ensuite le compilateur détermine quelles sections sont utilisées ne employant la règle "si aucune étiquette dans cette section n'est utilisée alors elle peut être éliminée".
  
Anyway, most problems using smartlinking stem from the fact that for the smallest result FPC generally requires "compile with smartlinking" to be on <b>WHEN COMPILING EACH AND EVERY UNIT, EVEN THE RTL</b>
+
Il y a quelques problèmes avec cette vision simpliste:
 +
* les méthodes virtuelles peuvent être implicitement appelées via leur VMTs. L'éditeur de liens GNU ne peut pas tracer des séquences à travers ces VMTs, donc elles sont toutes liées dans le binaire;
 +
* Les tables pour les chaînes de ressource font référence à chaque constante de chaîne, et donc toutes les constantes de chaîne sont liées (une des raisons pour lesquelles sysutils est gros).
 +
* Des symboles qui peuvent appelés depuis l'extérieur du binaire (c'est aussi possible pour les binaires ELF qui ne sont pas des bibliothèques) doivent être conservés. Cette dernière limitation est nécessaire pour éviter stripping des fonctions exportées depuis les bibliothèques partagées.
 +
* Les fonctions et propriétés publiées, qui doivent être conservées, constituent un autre problème de ce type. Les références aux fonctions/propriétés publiées peuvent être construites à la volée en utilisant des opérations de chaîne, et le compilateur ne peut tracer cela. C'est l'un des inconvénients de la réflexion.
 +
* Les propriétés publiées et les méthodes doivent être résolues en créant les noms de symboles en utilisant de la manipulation de chaîne, et doivent donc être liées si la classe est référencée n'importe où. Le code publié pourrait à son tour appeler un code privé/protégé/public et donc une inclusion assez importante.
  
The reason for this is simple. LD only could "smart" link units that were the size of an entire .o file until fairly recently. This means that for each symbol a separate .o file must be crafted. (and then these tens of thousands of .o files are archived in .a files). This is a time (and linker memory) consuming task, thus it is optional, and is only turned on for release versions, not for snapshots.  <b>Often people having problems with smartlinking use a snapshot that contains RTL/FCL etc that aren't compiled with smartlinking on.</b> Only solution is to recompile the source with smartlinking (-CX) on. See [[buildfaq]] for more info.
+
Un autre effet de bord important qui est logique (mais souvent oublié) est que cet algorithme liera tout ce qui est référencé dans les section initialization et finalization des unités, même si aucune fonctionnalité de ces unités n'est utilisée. Donc soyez prudent avec ce que vous utilisez.
  
In the future this will be improved when the compiler will emit smartlinking code by default, at least for the main targets. This is made possible by two distinct developments. First, the GNU linker LD now can smartlink more finely grained (at least on Unix) using --gc-sections, second the arrival of the FPC internal linker (in the 2.1.1 branch) for all working Windows platforms (wince/win32/win64). The smartlinking using LD --gc-sections still has a lot of problems because the exact assembler layout and numerous details with respect to tables must be researched, we often run into the typical problem with GNU development software here, the tools are barely tested (or sometimes not even implemented, see DWARF standard) outside what GCC uses/stresses.
+
Quoi qu'il en soit, la plupart des problèmes liés à l'utilisation de la liaison intelligente proviennent du fait que pour le plus petit résultat, FPC nécessite généralement que "compile with smartlinking" soit activé <b> LORS DE LA COMPILATION DE CHAQUE ET DE CHAQUE UNITÉ, MÊME LA RTL</b>.
  
The internal linker can now smartlink Lazarus (17 seconds for a full smartlink on my Athlon64 3700+ using about 250MB memory) which is quite well, but is windows only and 2.1.1 for now. The internal linker also opens the door to more advanced smartlinking that requires Pascal specific knowledge, like leaving out unused virtual methods (20% code size on Lazarus examples, 5% on the Lazarus IDE as a rough first estimate), and being smarter about unused resource strings. This is all still in alpha, and above numbers are probably too optimistic, since Lazarus is not working with these optimizations yet.
+
La raison pour cela est simple. LD ne pouvait faire des liaisons «intelligentes» que des unités de la taille d’un fichier .o entier jusqu’à assez récemment. Cela signifie que pour chaque symbole un fichier .o séparé doit être fabriqué (et ensuite ces dizaines de milliers de fichiers .o sont archivés dans un des fichiers .a). C'est une tâche consommatrice de temps (et de mémoire du lieur), donc c'est optionnel et activé seulement pour les versions de livraison, pas pour les instantanés (snapshots). <b>Souvent les gens qui ont des problèmes avec la liaison intelligente utilise un instantané qui contient des RTL/FCL etc qui n'ont pas été liées intelligemment</b>. La seule solution consiste à recomplier le source avec la liaison intelligente activée (-CX). Voir [[buildfaq]] plus d'infos.
  
=== Initialization and finalization sections ===
+
A l'avenir, ceci sera amélioré quand le compilateur émettra du code lié intelligemment par défaut, au moins pour les cibles principales. Ceci sera rendu possible par deux développements séparés. D'abord, LD l'éditeur de liens GNU peut maintenant lier intelligemment de manière plus fine (au moins sous Unix) en utilisant --gc-sections; ensuite l'arrivée de l'éditeur de liens interne à FPC (dans la brance 2.1.1) pourt toutes les plates-formes fonctionnant (wince/win32/win64). L'édition de liens intelligente utilisant LD --gc-sections a encore beaucoup de problèmes car la disposition exacte de l'assembleur et de nombreux détails concernant les tableaux doivent être recherchés, nous entrons souvent dans des problèmes typiques avec les développement GNU ici, les outils sont à peine testés (ou parfois même pas implémentés, voir le standard DWARF) en dehors de ce que GCC utilise/souligne. De plus, les versions des cibles non * nix sont souvent basées sur des versions plus anciennes (pensezà DOS, go32v2, amiga ici).
  
If you include a unit in ''USES'' section, even when USES'd indirectly via a different unit, then IF the unit contains initialization or finalization sections, that code and its dependancies is always linked in.  
+
L'éditeur de liens interne peut maintenant lier intelligemment Lazarus (17 secondes pour une liaison intelligente complète sur un Athlon64 3700+ utilisant environ 250 Mo de mémoire) ce qui est plutôt bon, mais seulement pour Windows et 2.1.1 pour le moment. L'éditeur de liens interne ouvre aussi la porte à des liaisons intelligentes plus avancées qui demande des connaissances spếcifiques à Pascal, comme abandonner une méthode virtuelle (20 % sur la taille du code des exemples Lazarus, 5 % sur l'EDI Lazarus en première estimation grossière), et traitant mieux les cjaîbne des ressource inutilisées. Tout ceci est en alpha, et les statistiques du dessus sont probablement trop optimistes, puisque Lazarus ne travaille pas encore avec ces optimisations.
  
A unit for which this is important is sysutils. As per Delphi compatibility, sysutils converts runtime errors to exceptions with a textual message. All the strings in sysutils together are a bit bulky. There is nothing that can be done about this, except removing a lot of initialisation from sysutils that would make it delphi incompatible. So this is more something for a embedded release, if such a team would ever volunteer.
+
Pendant une discussion sur Stack Overflow, certains [https://stackoverflow.com/questions/4519726/delphi-which-are-the-downsides-of-having-unused-units-listed-in-the-uses-clause/4519894#4519894  détails extra] viennent en avant (et la plupart les mêmes pour FPC comme pour Delphi, au moins sous Windows) :
  
=== Static binaries ===
+
=== Sections initialization et finalization ===
  
''(main article: [[Lazarus/FPC Libraries]])''
+
Si vous incluez une unité en section ''USES'', même quand il s'agit de USES indirects à travers une unité différente, alors SI l'unité contient des sections initialization ou finalization, ce code et ses dépendances sont toujours liés.
  
One can also make fully static binaries on any OS, incorporating all libraries into the binary. This is usually done to ease deployment, but has as tradeoff huge binaries. Since this is wizard territory I only mention this for the sake of completeness. People that can do this, hopefully know what they are doing.
+
Une unité pour laquelle c'est important est sysutils. Conformément à la compatibilité Delphi, sysutils convertit les erreurs d'exécution en exceptions avec un message textuel. Toutes les chaînes de sysutils réunies sont un peu volumineuses, il n'y a rien qui puisse être fait contre cela, à part de retirer un paquet d'initialisations de sysutils qui la rendra incompatible avc Delphi. C'est donc plus une chose pour une version embarquée, si une telle équipe se portait volontaire.
  
Instead of making static binaries, many programmers do dynamic linking / shared linking.
+
=== Binaires statiques ===
This _CAN_ generate a much, much smaller binary executable. However there are also cases where the binary gets bigger, specially on architectures like x86_64 where PIC is default on.
 
  
Dynamic linking (win32) and shared linking (*nix) are the same concept, but their internal workings vary, as can be easily seen by the fact that *nix systems need the shared libraries on the host to (cross-)link, and when linking a Windows binary you don't need the relevant .dlls on the system.
+
''(main article: [[Lazarus/FPC Libraries/fr|Lazarus/FPC Libraries]])''
  
=== Optimization ===
+
On peut aussi faire des binaires totalement statiques sur chaque système d'exploitation, en incorporant toutes les bibliothèques dans le binaire. Cela est fait en général pour faciliter le déploiement, mais cela produit par là-même d'énormes binaires. Puisqu'il s'agit du "territoire des sorciers" (wizard territory), je ne le mentionne que par souci d'exhaustivité. Les personnes qui font cela le font en connaissance de cause, nous l'espèrons.
  
Optimization can also shave off a bit of code size. Optimized code is usually tighter. (but only tenths of a percent) Make sure you use -O3.
+
Au lieu de produire des binaires statiques, des programmeurs font de la liaison dynamique / partagée. Cela PEUT générer un binaire exécutable beaucoup, beaucoup plus petit. Pourtant, il existe des cas où le binaire devient plus gros, en particulier sur des architectures comme x86_64 où le PIC est activé par défaut.
 +
La liaison dynamique (Win32) et la liaison partagée (*nix) sont le même concept, mais leur fonctionnement en interne est différent, comm cela peut être vu par le fait que les systèmes *nix ont besoin des bibliothèques partagées sur l'hôte pour faire le lien (croisé), alors que pour lier un binaire Windows vous n'avez pas besoin des DLLs nécessaires sur le système.
  
=== Lazarus lpr files ===
+
=== Optimisation ===
  
In Lazarus, if you add a package to your project/form you get it's registration unit added to the lpr file. The lpr file is not normally opened, if you want to edit it, first open it (via project -> view source). Then remove all the unnecessary units (Interfaces, Forms, and YOUR FORM units are only required, anything else is useless there, but make sure you don't delete units that only need to register things, such as image readers (jpeg) or testcases).
+
L'optimisation peut également réduire un peu la taille du code. Le code optimisé est généralement plus serré (mais seulement en dixième de pourcent). Assurez-vous d'utliser l'option -O3. Voir aussi [[Whole Program Optimization/fr|Optimisation globale de programme]] pour davantage de réduction de la taille du code.
  
You can save up to megabytes AND some linking dependencies too if you use big packages (such as glscene).
+
=== Fichier lpr de Lazarus ===
  
This kind of behaviour is typical for libraries that do a lot in the initialisation sections of units. Note that it doesn't matter where they are used (.lpr or a normal unit). Of course smartlinking tries to minimalize this effect
+
Dans Lazarus, si vous ajoutez un paquet à votre projet/fiche, vous obtenez que l'enregistrement de son unité est ajouté au fichier lpr. Le fichier lpr n'est normalement pas ouvert. Si vous voulez l'éditer, vous l'ouvrez d'abord (via Projet|Voir le code source du projet). Ensuite vous retirez toutes les unités non nécessaires telles que les interfaces, les fiches, les seules fiches requises sont vos propres unités de fiches, toutes les  autres choses ne sont pas nécessaires mais vous devez vous assurez de ne pas supprimer d'unité qui enregistre  des choses telles que des lecteurs d'images (jpeg) ou des cas de test.  
 +
(Ndt: C'est cependant un exercice risqué car cela supposerait de connaître l'évolution future des unités utilisées)
  
== 2.2.0 problems ==
+
Vous économisez alors des mégaoctets ET quelques dépendance en liaison aussi si vous utilisez des gros paquets (tels que glscene).
  
I routinely crack down on size discussions, to keep some sanity in them. This faq was meant for that.
+
Ce type de comportement est typique pour les bibliothèques qui font beaucoup de section d'initialisation d'unités. Remarquez que peu importe où elles sont utilisées (lpr ou unité normale). Bien sûr, la liaison intelligente essaie de minimiser ces effets.
  
However lately I've seen some size problems that were not of the routine kind. I suspect FPC changed behavior due to the internal linker in 2.2.0+. Since I want to try to be fair, I'll list my suspicions here. Note that these remarks hold for the default setup with internal linker enabled.
+
== Problèmes 2.2.0 ==
 +
(non traduit car sans doute obsolète bien que non vérifié)
 +
There appear to be some size problems in FPC 2.2.0 ''is this still relevant for 2.6.x/2.7.x?'' Note that these remarks hold for the default setup with internal linker enabled.
  
 
* It seems that FPC 2.2.0 doesn't strip if any -g option is used to compile the main program. This contrary to earlier versions where -Xs had priority over -g
 
* It seems that FPC 2.2.0 doesn't strip if any -g option is used to compile the main program. This contrary to earlier versions where -Xs had priority over -g
* It seems that FPC 2.2.0 doesn't always smartlink when crosscompiling. This can be problematic when compiling for windows, not only because of size, but also because dependencies are created to functions that might not exist.  
+
* It seems that FPC 2.2.0 doesn't always smartlink when crosscompiling. This can be problematic when compiling for windows, not only because of size, but also because dependencies are created to functions that might not exist.
  
 
== UPX ==
 
== UPX ==
 +
(non traduit, version 2.6 trop ancienne)
 +
'''Note: UPX support in makefiles, and the distribution of upx by FPC ceased after 2.6.0. New releases of FPC won't package upx any more'''
  
The whole UPX cult is a funny thing that largely originates in a mindless pursuit of minimal binary sizes. In reality it is a tool with advantages and disadvantages.  
+
The whole strange UPX cult originates mostly from a mindless pursuit of minimal binary sizes. In reality UPX is a tool with advantages and disadvantages.  
  
 
The advantages are:
 
The advantages are:
# The decompression is easy for the user because it is self contained
+
# The decompression is easy for the user because it is self-contained
# If, and only if, some size criterium is on the binary size itself (and not on e.g. the binary in a zip), like with demo contests, it can save some. However, specially in the lowest classes it might be worthwhile to code your compression yourself, because you probably can get the decompression code much tighter for binaries that don't stress all aspects of the binary format.
+
# Some size savings are made if (and only if) the size criterion is based on the binary size itself (as happens in demo contests). However, especially in the lowest classes it might be worthwhile to minimize the RTL manually and to code your compression yourself, because you can probably get the decompression code much tighter for binaries that don't stress all aspects of the binary format.
# For rarely used applications or applications run off removable media the diskspace saving may outweigh the performance/memory penalties.
+
# For rarely used applications or applications run from removable media the disk space saving may outweigh the performance/memory penalties.
# Many users don't know about UPX and judge applications on size (and yes this includes reviewers on shareware listings sites) so if other developers in the category use it you will look bloated if you do not follow suit. (odd argument since most shareware is a self extracting archive)
 
  
 
The disadvantages are:
 
The disadvantages are:
# worse compression (and also the decompression engine must be factored into _EACH_ binary)
+
# worse compression (and also the decompression engine must be factored into _EACH_ binary) by archivers (like ZIP) and setup creation tools
# decompression must occur each time.
+
# decompression occurs on every execution, which introduces a startup delay.
# Since windows XP+ now features a built-in decompressor for ZIP, the whole point of SFX goes away a bit.  
+
# Since Windows XP and later now feature a built-in decompressor for ZIP, the whole point of SFX goes away a bit.  
# UPXed binaries are increasingly being fingered by malware heuristics of popular antivirusses and mailfilters.
+
# UPXed binaries are increasingly being fingered by the malware heuristics of popular antivirus and mail-filtering apps.
# Binary that are internally compressed can't be memorymapped by windows, and must be loaded in its entirity. This means that the entire binary size is loaded into VM space (memory+swap), including resources.  
+
# An internally compressed binary can't be memorymapped by the OS, and must be loaded in its entirety. This means that the entire binary size is loaded into VM space (memory+swap), including resources.
 +
# You introduce another component (UPX, decompression stub) that can cause incompatibilities and problems.
  
 +
The memorymapping point needs some explanation: With normal binaries under Windows, all unused code remains in the .EXE, which is why Windows binaries are locked while running. Code is paged in 4k (8k on 64-bit) at a time as needed, and under low memory conditions is simply discarded (because it can be reloaded from the binary at any time). This also applies to graphic and string resources.
  
The last point can use some explanation: With normal binaries under windows, all unused code remains in the .EXE, which is why Windows binaries are locked while running. Code is paged in 4k (8k on 64-bit) at a time as needed, and under low mem conditions simply discarded (because it can be reloaded from bin at any time). This also goes for (graphical/string) resources.
+
A compressed binary must usually be decompressed in its entirety, to avoid badly affecting the compression ratio. So Windows has to decompress the whole binary on startup, and page the unused pages to the system swap, where they rot unused, and also take up extra swap space.
  
A compressed binary usually must be decompressed in its entirety, or compression ratio will hurt badly. So windows must decompress the whole binary on startup, and page the unused pages to the system swap, where they rot unused.
+
== Coûts de cadre d'application (Framework) ==
  
== Framework costs ==
+
Un cadre d'application (ou cadriciel) réduit grandement la quantité de travail pour développer une application.
  
A framework greatly decreases the amount of work to develop an application.
+
Cela a cependant un coût, car un framework n'est pas une simple bibliothèque, mais plutôt un sous-système entier qui traite de l'interfaçage avec le monde extérieur. Un framework est conçu pour un ensemble d'applications qui peuvent accéder à de nombreuses fonctionnalités (même si une seule application ne le peut pas).
  
This comes however at a cost, because a framework is not a mere library, but more a whole subsystem that deals with interfacing to the outside world. A framework is designed for a set of applications that can access a lot of functionality, (even if a single application might not).
+
Cependant, plus un framework peut accéder à des fonctionnalités, plus un certain sous-ensemble minimal devient grand. Pensze à l'internationalisation, au support des ressources, aux environnements de traduction (traduction sans recompilation), messages d'erreur siginificatifs pour les exceptions de base. Tout ceci est appelé les frais généraux du cadre d'application (framework overhead).
  
However the more functionality a framework can access, the bigger a certain minimal subset becomes. Think of internationalization, resource support, translation environments (translation without recompilation), meaning error messages for basic exceptions etc. This is the so called framework overhead.
+
La taille d'une application vide n'est pas due aux inefficiences du compilateur mais aux frais généraux du cadre d'application. Le compilateur ôtera le code inutilisé automatiquement, mais tout le code ne peut pas l'être. La conception du cadre d'application détermine quel code le compilateur est capable d'enlever lors de la compilation.
  
This size of empty applications is not caused by compiler inefficiencies, but by framework overhead. The compiler will remove unused code automatically, but not all code can be removed automatically. The design of the framework determines what code the compiler will be able to remove at compile time.
+
Certains cadre d'application sont à l'origine de très petits frais généraux, alors que d'autres en amènent de plus gros. Tailles attendues pour les applications vides sur des cadriciels bien connus:
  
Some frameworks cause very little overhead, some cause a lot of overhead. Expected binary sizes for empty applications on well known frameworks:
+
* Aucun cadriciel (seulement la RTL): +/- 25kb
* No framework (RTL only): +/- 25kb
+
* Aucun cadriciel (RTL+sysutils seulement): +/- 100-125kb
* No framework (RTL+sysutils only): +/- 100-125kb
+
* [[MSEide_&_MSEgui/fr|MSEGUI]]: +/- 600kb
* [[MSEide_&_MSEgui|MSEGUI]]: +/- 600kb
 
 
* Lazarus LCL: +/- 1000kb
 
* Lazarus LCL: +/- 1000kb
 
* Free Vision: +/- 100kb  
 
* Free Vision: +/- 100kb  
* [[KOL-CE|Key Objects Library]]: +/- 50kb
+
* [[KOL-CE/fr|Key Objects Library]]: +/- 50kb
  
In short, choose your framework well. A powerful framework can save you lots of time, but, if space is tight, a smaller framework might be a better choice. But be sure you really need that smaller size. A lot of amateurs routinely select the smallest framework, and end up with unmaintainable applications and quit. It is also no fun having to maintain applications in multiple frameworks for a few kb.  
+
En bref, choisissez bien votre cadriciel. Un cadriciel puissant peut vous faire économiser beaucoup de temps, mais si l'espace est compté (cas du code embarqué), un cadriciel plus petit pourrait être un meilleur choix. Mais assurez d'avoir besoin de ce gain de place. De nombreux amateurs choisissent par habitude le plus petit cadriciel et finissent avec du code immaintenable puis arrêtent. Ce n'est pas drôle de maintenir des applications dans de multiples cadriciels pour gagner quelques ko.
  
Note that e.g. the Lazarus framework is relatively heavy due to use of RTTI/introspection for its streaming mechanisms, not (only) due to source-size . RTTI makes more code reachable, degrading smartlinking performance.
+
Remarquez par exemple que le cadriciel de Lazarus est relativement lourd du fait de l'utilisation de la RTTI et de l'introspection pour ses mécanismes de flux, et pas seulement la taille du source. la RTTI rend plus de code accessible en dégradant les performances de la liaison intelligente.
  
= Unrealistic expectations =
+
= Attentes irréalistes =
  
A lot of people simply look at the size of a binary and scream '''bloat!'''. When you try to argue with them, they hide behind comparisons (but TP only produces...), they never really say 'why' they need the binary to be smaller at all costs. Some of them don't even realise that 32-bit code is ALWAYS bigger than 16-bit code, or that OS independance comes at a price, or ...,or ..., or...
+
Beaucoup de gens regardent la taille d'un binaire et s'écrient '''Gonflé!'''. Quand vous tentez d'argumenter avec eux, ils se cachent derrière des comparaisons (mais TP produit ...), ils ne disent jamais réellement 'pourquoi' ils sont besoin d'un binaire qui soit plus faibles sur tous les coûts. Certains d'entre eux ne réalisent même pas qu'un code 32-bit (maintenant 64-bit) est TOUJOURS plus gros qu'un code 16-bit (maintenant 32-bit) ou que l'indépendance à un SE a un coût ou ..., ou ..., ou ...
  
As said earlier, with the current HD sizes, there is not that much reason to keep binaries extremely small. FPC binaries being 10, 50 or even 100% larger than compilers of the previous millenium shouldn't matter much. A good indicator that these views are pretty emotional and unfounded is the overuse of UPX (see above), which is a typical sign of binary-size madness, since technically it doesn't make much sense.
+
Comme dit plus haut, avec la taille actuelle des disques durs, il n'y a pas de raison de garder les binaires avec des tailles très petites. les binaires FPC étant 10, 50 ou même 100% plus grands que ceux des compilateurs du précédent millénaire ne devraient pas avoir beaucoup d'importance. Un bon indicateur de ces visions est le sur-emploi franchement émotionnel et infondé d'UPX (voir au dessus), qui est un signe de la folie de la taille du binaire, puisque cela n'a pas de sens techniquement parlant.
  
So where is this emotion coming from them? Is it just resisting change, or being control-freaks? I never saw much justified cause, except that sometimes some of them were pushing their own inferior libraries, and tried to gain ground against well established libs based on size arguments. But this doesn't explain all cases, so I think the binary size thing is really the last "640k should be enough for anybody" artefact. Even though not real, but just mental.  
+
Alors d'où vient cette émotion ? S'agit-il simplement de résister au changement ou d'être des maniaques de contrôle ? Je n'ai jamais vu beaucoup de cause justifiée, sauf que parfois certains d'entre eux poussaient leurs propres bibliothèques inférieures et essayaient de gagner du terrain contre des bibliothèques bien établies basées sur des arguments de taille. Mais cela n'explique pas tous les cas, donc je pense que la taille binaire est vraiment le dernier artefact "640k devrait être suffisant pour n'importe qui" (Ndt: citation de Bill Gates). Même si ce n'est pas réel, mais juste mental.
  
A dead giveway for that is that the number of realistic patches in this field is near zero, if not zero. It's all maillist discussion only, and trivial RTL mods that hardly gain everything, and seriously hamper making real applications and compatability. (and I'm not a compatability freak to begin with).  
+
Une fausse révélation pour cela est que le nombre de correctifs réalistes dans ce domaine est proche de zéro, sinon zéro. Ce sont uniquement des discussions maillist, et des mods RTL triviaux qui ne gagnent presque rien et qui entravent sérieusement la création de vraies applications et la compatibilité (et je ne suis pas un maniaque de la compatibilité pour commencer).
Nobody sits down for a few days and makes a thorough investigation and comes up with patches. There are no cut down RTLs externally maintained, no patch sets etc, while it would be extremely easy. '''Somehow people are only after the last byte if it is easy to achieve, or if they have something "less bloated" to promote.'''
+
Personne ne s'assoit pendant quelques jours et fait une enquête approfondie et propose des correctifs. Il n'y a pas de RTL réduite entretenue en externe, pas de jeux de correctifs, etc., alors que ce serait extrêmement facile. '''D'une manière ou d'une autre, les gens ne sont après le dernier octet que si c'est facile à réaliser, ou s'ils ont quelque chose de "moins gonflé" à promouvoir.'''
  
Anyway, the few embedded people I know that use FPC intensively all have their own customized cut back libraries. For one person internationalization matters even when embedded (because he talks a language with accents), and exceptions do not, for somebody else requirements are different again. Each one has its own tradeoffs and choices, and if space is 'really' tight, you don't compromise to use the general release distro.
+
{{Note| le paragraphe ci-dessus est toujours vrai, près de cinq ans après sa rédaction.}}
  
And yes, FPC could use some improvements here and there. But those shouldn't hurt the "general programming", the multiplatform nature of FPC, the ease of use and be realistic in manpower requirements. Complex things take time. Global optimizers don't fall from the sky readily made.
+
Quoi qu'il en soit, les quelques personnes embarquées que je connais qui utilisent FPC de manière intensive ont toutes leurs propres bibliothèques personnalisées. Pour une personne, l'internationalisation compte même lorsqu'elle est intégrée (car elle parle une langue avec des accents), et les exceptions ne comptent pas, pour quelqu'un d'autre, les exigences sont encore différentes. Chacun a ses propres compromis et choix, et si l'espace est «vraiment» restreint, vous ne faites pas de compromis pour utiliser la distribution générale.
  
== Comparisons with GCC ==
+
Et oui, FPC pourrait utiliser quelques améliorations ici et là. Mais ceux-ci ne devraient pas nuire à la «programmation générale», à la nature multiplateforme du FPC, à la facilité d'utilisation et à être réaliste dans les besoins en main-d'œuvre. Les choses complexes prennent du temps. Les optimiseurs globaux ne tombent pas du ciel facilement
  
Somewhat less unrealistic are comparisons with GCC. Even the developers mirror themselves (and FPC) routinely against gcc. Of course gcc is a corporate sponsored behemoth, who is also the Open Source's world favorite. Not all comparisons are reasonable or fair. Even compilers that base themselves on GCC don't support all heavily sponsored "c" gcc's functionality.
+
== Comparaisons avec GCC ==
  
Nevertheless, considering the differences in project size, FPC does a surprisingly good job. Speed is ok, except maybe for some cases of heavily scientific calculating, binary sizes and memory use are sufficient or even better in general, the number of platforms doesn't disappoint (though it is a pity that 'real' embedded targets are missing).
+
Les comparaisons avec GCC sont un peu moins irréalistes. Même les développeurs se reflètent (et FPC) régulièrement dans GCC. Bien sûr, GCC est un monstre sponsorisé par une entreprise, qui est également le favori mondial de l'Open Source. Toutes les comparaisons ne sont pas raisonnables ou équitables. Même les compilateurs qui se basent sur GCC ne supportent pas toutes les fonctionnalités "c" de gcc fortement sponsorisées.
  
Another issue here is that freepascal generally statically links (because it is not abi stable and would be unlikely to be on the target system already even if it was) its own rtl. GCC dynamically links against system libraries. This makes very small (in terms of source size) programs made with fpc have significantly larger binaries than those made with gcc. It's worth mentioning here, that the binary size has nothing to do with the memory footprint of the program. FPC is usually much better in this regard than gcc.
+
Néanmoins, compte tenu des différences de taille des projets, FPC fait un travail étonnamment bon. La vitesse est correcte, sauf peut-être pour certains cas de calcul fortement scientifique, les tailles binaires et l'utilisation de la mémoire sont suffisantes voire meilleures en général, le nombre de plates-formes ne déçoit pas (même s'il est dommage qu'il manque de 'vraies' cibles embarquées).
  
Still, I think that considering the resources, FPC is doing extraordinarily well.
+
Un autre problème ici est que FreePascal lie généralement statiquement (car il n'est pas ABI stable et il est peu probable qu'il soit déjà sur le système cible même s'il l'était) son propre RTL. GCC établit des liens dynamiques avec les bibliothèques système. Cela fait que les très petits programmes (en termes de taille de source) créés avec fpc ont des binaires beaucoup plus grands que ceux créés avec GCC. Il convient de mentionner ici que la taille binaire n'a rien à voir avec l'empreinte mémoire du programme. FPC est généralement bien meilleur à cet égard que GCC.
  
== Comparisons with Delphi ==
+
Pourtant, je pense que compte tenu des ressources, FPC se porte extraordinairement bien.
  
In comparisons with Delphi one should keep in mind that 32-bit Delphi's design originates in the period that a lot of people DIDN'T even have pentium-I's, and the developer that had 32MB RAM was a lucky one. Moreover Delphi was not designed to be portable.
+
== Comparaisons avec Delphi ==
  
Considering this, Delphi scaled pretty well, though there is always room for improvement, and readjustments that correct historical problems and tradeoffs. (it is a pretty well known fact that a lot of assembler routines in newer Delphi's were slower than their Pascal equivalents, because they were never updated for newer processors. Only the recent D2006 is said to have corrected this).  
+
Dans les comparaisons avec Delphi, il faut garder à l'esprit que la conception de Delphi 32 bits provient de la période où beaucoup de gens n'avaient même pas de Pentium-I, et le développeur qui avait 32 Mo de RAM était chanceux. De plus, Delphi n'a pas été conçu pour être portable.
  
Still, slowly on the compiler front, FPC isn't Delphi's poor cousin anymore. The comparisons are head-on, and FPC 2.1.1 winning over Delphi is slowly getting the rule, and not the exception anymore.
+
Compte tenu de cela, Delphi a assez bien évolué, bien qu'il y ait toujours place à l'amélioration et à des réajustements qui corrigent les problèmes historiques et les compromis. (C'est un fait assez bien connu que beaucoup de routines d'assembleur dans les plus récents Delphi étaient plus lentes que leurs équivalents Pascal, car elles n'ont jamais été mises à jour pour les processeurs plus récents. On dit que cela n'a été corrigé que depuis Delphi 2006.)
  
Of course that is only the base compiler. In other fields there is still enough work to do, though the internal linker helps a lot. The debugger won't be fun though :-)  Also in the language interoperability (C++, Obj C, JNI) and shared libraries is lots of work to do, even within the base system.
+
Pourtant, lentement sur le front du compilateur, FPC n'est plus le pauvre cousin de Delphi. Les comparaisons sont frontales, et le gain de FPC 2.1.1 sur Delphi devient lentement la règle, et non plus l'exception.
  
== Comparisons with .NET/Java ==
+
Bien sûr, ce n'est que le compilateur de base. Dans d'autres domaines, il y a encore assez de travail à faire, bien que l'éditeur de liens interne aide beaucoup. Le débogueur ne sera pas amusant cependant :-) Aussi dans l'interopérabilité des langages (C ++, Obj C, JNI) et les bibliothèques partagées, il y a beaucoup de travail à faire, même dans le système de base.
  
Be very carefull with comparisons to these JIT compiled systems, JITed programs have different benchmark characteristics and also extrapolating results from benchmarks to full programs is different.
+
== Comparaisons avec .NET/Java ==
  
While a JIT can do a great job sometimes (specially in small programs that mostly consist out of a single tight loop), but this good result often doesn't scale. Overall my experience is that statically compiled code is usually faster in most code that is not mainly bound by some highly optimizable tight loop, despite the numerous claims on the net otherwise.
+
Soyez très prudent dans les comparaisons avec ces systèmes compilés JIT: les programmes JIT-é ont des caractéristiques de référence différentes, et l'extrapolation des résultats des benchmarks aux programmes complets est également différente.
  
A fairly interesting quantitative source for this is this [http://shootout.alioth.debian.org/gp4sandbox/faq.php#fullcpu Shootout faq] entry. Another interesting one is [http://www.folding-hyperspace.com/program_tip_11.htm memory allocation in JVM/.NET].
+
Alors qu'un JIT peut parfois faire un excellent travail (en particulier dans les petits programmes qui consistent principalement en une seule boucle serrée), mais ce bon résultat ne s'adapte souvent pas. Dans l'ensemble, mon expérience est que le code compilé statiquement est généralement plus rapide dans la plupart des codes qui ne sont pas principalement liés par une boucle serrée hautement optimisable, malgré les nombreuses affirmations sur le net.
  
Note that since about an year (in 2007), java 6 suddenly caused a significant jump in the Java shootout-ratings, and starts touching the bottom of normal native compilers. This shows that one must be very carefully echoing sentiments on the web (both positive and negative) and stick to own measuring, with the border conditions trimmed to the application domain that you are in.
+
Une source quantitative assez intéressante pour cela est cette entrée [http://shootout.alioth.debian.org/gp4sandbox/faq.php#fullcpu Shootout faq]. Une autre intéressante est [http://www.folding-hyperspace.com/program_tip_11.htm memory allocation in JVM/.NET].
 +
 
 +
Notez que depuis 2007, Java 6 a soudainement provoqué un saut significatif dans les évaluations de fusillade Java (Java shootout-ratings), et commence à toucher le fond des compilateurs natifs normaux. Cela montre qu'il faut être très prudent en faisant écho aux sentiments sur le Web (à la fois positifs et négatifs) et s'en tenir à sa propre mesure, avec les conditions aux limites ajustées au domaine d'application dans lequel vous vous trouvez.
 +
 
 +
=Analyse de diverses options=
 +
Tests sur Lazarus 0.9.29 avec FPC 2.4 (FPC 2.2.4 sous Windows).
 +
 
 +
''Compilateur optimisé'' signifie:
 +
* 1. Projet|Options du projet...|Options du compilateur|Compilation et édition de liens|Lien intelligent (-CX) -> Coché
 +
* 2. Projet|Options du projet...|Options du compilateur|Débogage| Décocher tout sauf 'Eliminer les symboles de l'exécutable Strip' (-Xs) -> Coché
 +
* 3. Projet|Options du projet...|Options du compilateur|Compilation et édition de liens|Lier intelligemment (-XX) -> Coché
 +
Le point le plus important semble être le 2. Pour une simple application la taille de l''exécutable serait de 1-3 Mo au lieu de 15-20 Mo.
 +
* 4. (facultatif) Projet|Options du projet...|Options du compilateur|Compilation et édition de liens|Plus petit plutôt que plus rapide (-Os) -> Coché (Avertissement: cela peut diminuer les performances en vitesse d'exécution).
 +
 
 +
 
 +
''Lazarus par défaut'' signifie comme installé depuis le setup.
 +
 
 +
''LCL sans information de débogage'' signifie après reconstruction de lk'IDE Lazarus et de la LCL sans information de débogage (-g-).
 +
 
 +
<TABLE WIDTH=642 BORDER=0 CELLPADDING=1 CELLSPACING=0>
 +
<TR VALIGN=TOP>
 +
<TH WIDTH=263></TH>
 +
<TH WIDTH=14>&nbsp; &nbsp;</TH>
 +
<TH WIDTH=111>Lazarus par défaut</TH>
 +
<TH WIDTH=14>&nbsp; &nbsp;</TH>
 +
<TH WIDTH=220>LCL sans information de débogage</TH>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263><U>Ubuntu 64 bits / Lazarus 64 bits</U></TD>
 +
<TD COLSPAN=4 WIDTH=372></TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>Application par défaut</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=111>13,4&nbsp; Mb</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=220>7,5 Mb / 8</TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>Compilateur optimisé</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=111>4,4 Mb</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=220>2,70 Mb (0.29svn FPC2.4 2,5)</TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>&nbsp; &nbsp;</TD>
 +
<TD COLSPAN=4 WIDTH=372></TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263><U>Ubuntu 32 bits / Lazarus 32 bits</U></TD>
 +
<TD COLSPAN=4 WIDTH=372></TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>Application par défaut</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=111>19,6&nbsp; Mb</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=220>5,7 Mb</TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>Compilateur optimisé</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=111>2,9 Mb</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=220>1,6 Mb</TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>&nbsp; &nbsp;</TD>
 +
<TD COLSPAN=4 WIDTH=372></TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263><U>Windows XP 32 bits / Lazarus 32 bits</U></TD>
 +
<TD COLSPAN=4 WIDTH=372></TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>Application par défaut</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=111>11,8 Mb</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=220>2,14 Mb</TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>Compilateur optimisé</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=111>1,62 Mb</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=220>1,50 Mb</TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>&nbsp; &nbsp;</TD>
 +
<TD COLSPAN=4 WIDTH=372></TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263><U>Windows Seven 64 bits / Lazarus 64 bits</U></TD>
 +
<TD COLSPAN=4 WIDTH=372></TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>Application par défaut</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=111>12,3&nbsp; Mb</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=220>3,20 Mb</TD>
 +
</TR>
 +
<TR VALIGN=TOP>
 +
<TD WIDTH=263>Compilateur optimisé</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=111>2,14 Mb</TD>
 +
<TD WIDTH=14>&nbsp; &nbsp;</TD>
 +
<TD WIDTH=220>2,16 Mb</TD>
 +
</TR>
 +
</TABLE>
 +
 
 +
=Voir aussi=
 +
 
 +
* [[File_size_and_smartlinking/fr|Taille de fichier et liaison intelligente]]
 +
* [[Lazarus_Faq/fr#Pourquoi_les_fichiers_binaires_produits_sont-ils_si_volumineux_.3F|Lazarus FAQ - Pourquoi les binaires produits sont si gros ?]]
 +
https://wiki.freepascal.org/

Latest revision as of 12:55, 5 December 2020

Deutsch (de) English (en) français (fr) русский (ru) 中文(中国大陆)‎ (zh_CN)

Introduction

Cette page porte sur les tailles de binaires. Au fil des années il y a eu beaucoup de confusion sur les tailles binaires FPC et Lazarus. Avant de faire des remarques dans les listes de diffusion, SVP, lisez cette FAQ.

La principale raison pour cette FAQ est que la plupart des discussions sur ce sujet ont tendance à tomber trop rapidement dans les détails. Aussi, l'opinion de gens qui crient "envahit" presque tout et obscurcit l'image globale souvent plus qu'il ne contribue à la clarté.

Règle générale, que sont les tailles réalistes actuels pour les binaires FPC/Lazarus ?

  • Tout ce qui est en dessous de 1 Mo n'est pas un problème.
    • Assurez-vous qu'ils sont correctement dépouillés (stripped) et liés intelligemment avant la mesure et que TOUTES les bibliothèques sont construites en utilisant la liaison intelligente.
    • NE PAS FAIRE DE binaires UPX par habitude, a moins d'avoir de très bonnes raisons de le faire (voir en dessous). La taille est moins importante que la charge mémoire qu'un binaire décompressé provoque. La mémoire est plus chère que l'espace disque. La plupart des outils d'accès à distance implémente la compression dans leur tunnel.
  • Avec de petites apps, c'est plus dur à estimer. C'est parce que la taille exacte de la RTL dépend de l'OS. Toutefois, 100ko de binaire autonome qui fait quelque chose peut être fait en général en dessous de 50ko.
    • Sous windows 20k d'IHM utilisant des binaires ne sont pas un problème.
    • L'unité SysUtils contient l'internationalisation, des messages d'erreur en texte, la gestion des exceptions et d'autres trucs qui sont toujours liés quand cette unité est employée (penser à un total de 40-100k).
  • Les apps Lazarus sur Windows font environ 500ko, mais grossissent rapidement à 1,5 Mo et de plus en plus avec les widgets Lazarus utilisés. Les apps binaires Lazarus peuvent passer à plus de 100 Mo quand les infos de débogage sont liées dedans (comparable aux infos TD32 dans Delphi).
    • C'est un peu plus que lorsqu'on recompile avec une ancienne version de Delphi, et un peu moins qu'avec les versions modernes de Delphi (D2009+ la taille minimale de la RTL bondit fortement), c'est le prix de pour la compatibilité croisée de plate-forme et la maintenabilité des projets.
    • Quand le moment est atteint l'ajout de code supplémentaire n'introduit pas de nouvelles dépendances, cette croissance rapide disparaît.
    • Le point des 1,5Mo du dessus est une règle d'or. Il dépend beaucoup du style de création de votre IHM et du nombre de différents Widgets que vous utilisez et de leur complexité.
    • Pour les applications Lazarus, une partie du binaire n'est pas du code, la plupart sont des chaînes et des tables.
  • Les simples binaires Linux/FreeBSD sont plus gros que les GCC correspondants. C'est parce qu'ils n'utilisent pas de bibliothèques partagées (ce que vous pouvez facilement voir ldd ./xx)
  • Les binaires 64 bits sont toujours plus gros que leurs équivalents x86. En général, les plates-formes RISC génèrent aussi des binaires légèrement plus gros.

Pourquoi les binaires sont si gros ?

Réponse: Ils ne sont pas censés être grand.

Si vous les percevez comme gros, alors

  • soit vous n'avez pas configuré FPC proprement, ou
  • vous avez une attente irréaliste de la taille que devrait avoir le binaire
  • vous essayer de faire quelque chose pour laquelle FPC n'est pas conçu.

Le dernier est sans le moins probable des trois. Je vais traiter ces trois cas rapidement dans les prochains paragraphes.

Est-ce mauvais quand les binaires sont gros ?

Bien, cela dépend de l'ampleur du parcours. Mais il est sûr de dire que presque personne ne devrait être inquiet d'avoir des binaires gros de quelques Mo ou même plus de 10 Mo pour des applications considérables.

Cependant, il y a encore quelques catégories qui pourraient vouloir avoir un certain contrôle sur les fichiers binaires en les gardant petits.

  1. Le monde de la programmation embarquée évidemment (et alors je ne veux pas dire les PC embarqués qui ont toujours des dizaines de Mo).
  2. les gens qui distribuent vraiment quotidiennement par modem
  3. Concours, mesures de performance

Notez qu'une idée fausse souvent citée est celle que des binaires plus gros sont plus lents en fonctionnement. En général, cela n'est pas vrai, 'exotic last-cycle stuff as code cachelines'(non traduit) mis à part.

Embarqué

Alors que Free Pascal est raisonnablement utilisable pour des usages embarqués ou de système, les décisions d'ingénierie de la version finale et de compromis sont basées sur les exigences de construction d'applications plus générales, bien que certaines des cibles les plus intégrées (comme DOS 16 bits ou ARM/AVR/MIPS (= PIC32) étendent cela à la limite.

Si vous avez des besoins aussi spécialisés pour des objectifs plus réguliers, vous pouvez définir un projet dans l'ombre (quelque chose comme les versions spécialisées de certaines distros Linux qui sont disponibles). Ennuyer l'équipe FPC qui est déjà surchargée avec ces besoins spécifiques n'est pas une option, d'autant plus que la moitié des utilisateurs embarqués sérieux roulent de toutes façons.

distribution par modem

Le cas du modem n'est pas seu1ement "télécharger depuis Internet" ou "mon shareware doit être aussi petit que possible", mais p.ex. dans mon ancien travail nous faisions un tas de déploiement vers nos clients et vers nos sites externes via le bureau distant sur le RNIS. Mais même avec un modem 56k, vous ne pouvez pas envoyer 1 Mo en moins de 5 minutes.

Veillez à ne pas abuser de cet argument pour essayer de fournir un fondement rationnel mal placé pour une opinion émotionnelle sur la taille binaire. Si vous faites ce point, cela ne sert à rien sans une analyse statistique approfondie du pourcentage d'utilisateurs de modem réels que vous avez pour votre application (ma plupart des utilisateurs de logiciels ne téléchargent pas depuis Internet mais depuis les CD des magazines de shareware (NdT: ce point de vue n'est plus valbale actuellement).

Concours

Une autre raison pour garder les binaires petits sont les comparaison de langages (comme le Language Shootout). Cependant ceci est plus comme résoudre un puzzle, et pas vraiment lié au génie logiciel responsable.

Configuration de compilateur incorrecte

Je ne suis pas en train d'expliquer chaque aspect de la configuration du compilateur de manière détaillée, puisque c'est une FAQ, non un manuel. C'est juste un survol. Lire manuals et buildfaq de manière approfondie pour une information plus fondamentale.

Il y a généralement plusieurs raisons de pourquoi un binaire semble plus gros qu'attendu. Cette FAQ couvre les raisons les plus courantes, en ordre décroissant de probabilité:

  1. le binaire contient encore des informations de débogage.
  2. le programme n'a pas été (complétement) lié intelligemment.
  3. Le binaire inclut des unités contenant des sexctions d'initialisation qui execute beaucoup de code.
  4. vous liez statiquement des biblitohèques externes, plus qu'utilisez des liaisons dynamiques (bibliothèques partagées).
  5. L'optimisation n'est pas (complètement) activée.
  6. Le fichier de projet Lazarus (lpr) a des unités de paquet dans sa section uses (c'est fait automatiquement par Lazarus)

Dans le futur, les liaisons partagées vers une bibliothèque d'exécution FPC et/ou Lazarus devrait changer cette image de manière significative. Bien sûr, cela vous aurez à distribuer une grosse DLL withe pleins d'autres trucs dedans qui vous amènera à des problèmes de versioning).

Tout cela est encore dans le futur, il est donc difficile de quantifier l'impact sur les tailles binaires. Surtout parce que la liaison dynamique a également une surcharge de taille (en plus du code inutilisé dans la bibliothèque partagée).

Information de débogage

Free Pascal utilise GDB comme débogueur et LD comme éditeur de liens. Ceux-ci travaillent avec des infos de débogage dans le binaire, dans l'ancien format stabs ou le plus récent dwarf. Les gens voient souvent p.ex. des binaires qui font 40 Mo. La bonne taille devrait être autour de 6Mo, le reste sont des informations de débogage (et peut-être 6 Mo pour de la liaison intelligente mal faite).

L'info de débogage Stabs est plutôt encombrante, mais a l'avantage d'être relativement indépendante du format binaire. Elle a été remplacée par DWARF sauf pour certaines plates-formes légataires.

Il y a souvent confusion en ce qui concerne les informations de débogage, qui est causée par le strip dans de nombreuses versions win32 des binutils. Aussi certaines versions du binaire Win32 de strip n'élimine pas totalement les infos de débogage générées par FPC. Donc les gens bascule le drapeau tel que -Xs (ligne de commande Lazarus/IDE ou FPC) et suppose que cela marche alors que non. FPC a été adapté pour remédier à cela.

Donc dans le doute, tenter toujours de faire le strip manuellement, et sur Windows, avec plusieurs binaires STRIP différents.

Ce genre de problème devient plus rare particulièrement sur Windows, depuis que l'éditeur de liens interne traite ces problèmes de façon plus consistante. Néanmoins (nez en moins ;-), il s'applique toujours pour les personnes qui utilisent des cibles exotiques pendant un certain temps encore.

Vous pouvez utiliser le système de Strip pour livrer la même construction entre la version allégée (strippée) pour l'utilisateur et conserver la version complète (non strippée) pour p.ex. l'interprétation des adresses de trace arrière. Ainsi, si vous faites des livraisons formelles, conservez toujours une copie complète du binaire que vous enverrez qui sera allégé.

La conception de GDB lui-même vous laisse garder et utiliser les informations de débogage en dehors du fichier binaire (infos de débogage externes), dans un fichier séparé .gdb. La taille du binaire résultant n'est pas augmentée du fait des infos de débogage, et vous pouvez toujours réussir à déboguer le binaire. Vous n'avez pas besoin du fichier .dbg pour exécuter l'application, il est utilisé uniquement par le débogueur. Comme les infos de débogage sont externes, il est utile d'utiliser strip.

Pour compiler votre application de cette façon, vous devriez utiliser la bascule -Xg ou l'option correspondante dans l'IHM de Lazarus : dans 'Projet|Options du projet|Options du compilateur|Débogage', laissez 'Generate info for the debugger' active et activez 'Use external debug symbols file'.

BigExe FR.png

Une application avec une fenêtre vide pour Win32, compilée avec des infos de débogage externes doit occuper environ 1 Mo, et le fichier .dbg environ 10 Mo.

Liaison intelligente

(main article principal: File size and smartlinking)

La principe fondamental de la liaison intelligente est simple et bien connu : ne pas lier ce qui ne sert pas. Ceci a bien sûr un bon effet sur la taille du binaire.

Pourtant, le compilateur est seulement un programme et n'a pas une boule de cristal magique pour voir ce qui est utilisé, aussi l'implémentation de base est plutôt comme cela :

  • Le compilateur divise le code en soi-disant "sections" qui sont assez petites.
  • Ensuite le compilateur détermine quelles sections sont utilisées ne employant la règle "si aucune étiquette dans cette section n'est utilisée alors elle peut être éliminée".

Il y a quelques problèmes avec cette vision simpliste:

  • les méthodes virtuelles peuvent être implicitement appelées via leur VMTs. L'éditeur de liens GNU ne peut pas tracer des séquences à travers ces VMTs, donc elles sont toutes liées dans le binaire;
  • Les tables pour les chaînes de ressource font référence à chaque constante de chaîne, et donc toutes les constantes de chaîne sont liées (une des raisons pour lesquelles sysutils est gros).
  • Des symboles qui peuvent appelés depuis l'extérieur du binaire (c'est aussi possible pour les binaires ELF qui ne sont pas des bibliothèques) doivent être conservés. Cette dernière limitation est nécessaire pour éviter stripping des fonctions exportées depuis les bibliothèques partagées.
  • Les fonctions et propriétés publiées, qui doivent être conservées, constituent un autre problème de ce type. Les références aux fonctions/propriétés publiées peuvent être construites à la volée en utilisant des opérations de chaîne, et le compilateur ne peut tracer cela. C'est l'un des inconvénients de la réflexion.
  • Les propriétés publiées et les méthodes doivent être résolues en créant les noms de symboles en utilisant de la manipulation de chaîne, et doivent donc être liées si la classe est référencée n'importe où. Le code publié pourrait à son tour appeler un code privé/protégé/public et donc une inclusion assez importante.

Un autre effet de bord important qui est logique (mais souvent oublié) est que cet algorithme liera tout ce qui est référencé dans les section initialization et finalization des unités, même si aucune fonctionnalité de ces unités n'est utilisée. Donc soyez prudent avec ce que vous utilisez.

Quoi qu'il en soit, la plupart des problèmes liés à l'utilisation de la liaison intelligente proviennent du fait que pour le plus petit résultat, FPC nécessite généralement que "compile with smartlinking" soit activé LORS DE LA COMPILATION DE CHAQUE ET DE CHAQUE UNITÉ, MÊME LA RTL.

La raison pour cela est simple. LD ne pouvait faire des liaisons «intelligentes» que des unités de la taille d’un fichier .o entier jusqu’à assez récemment. Cela signifie que pour chaque symbole un fichier .o séparé doit être fabriqué (et ensuite ces dizaines de milliers de fichiers .o sont archivés dans un des fichiers .a). C'est une tâche consommatrice de temps (et de mémoire du lieur), donc c'est optionnel et activé seulement pour les versions de livraison, pas pour les instantanés (snapshots). Souvent les gens qui ont des problèmes avec la liaison intelligente utilise un instantané qui contient des RTL/FCL etc qui n'ont pas été liées intelligemment. La seule solution consiste à recomplier le source avec la liaison intelligente activée (-CX). Voir buildfaq plus d'infos.

A l'avenir, ceci sera amélioré quand le compilateur émettra du code lié intelligemment par défaut, au moins pour les cibles principales. Ceci sera rendu possible par deux développements séparés. D'abord, LD l'éditeur de liens GNU peut maintenant lier intelligemment de manière plus fine (au moins sous Unix) en utilisant --gc-sections; ensuite l'arrivée de l'éditeur de liens interne à FPC (dans la brance 2.1.1) pourt toutes les plates-formes fonctionnant (wince/win32/win64). L'édition de liens intelligente utilisant LD --gc-sections a encore beaucoup de problèmes car la disposition exacte de l'assembleur et de nombreux détails concernant les tableaux doivent être recherchés, nous entrons souvent dans des problèmes typiques avec les développement GNU ici, les outils sont à peine testés (ou parfois même pas implémentés, voir le standard DWARF) en dehors de ce que GCC utilise/souligne. De plus, les versions des cibles non * nix sont souvent basées sur des versions plus anciennes (pensezà DOS, go32v2, amiga ici).

L'éditeur de liens interne peut maintenant lier intelligemment Lazarus (17 secondes pour une liaison intelligente complète sur un Athlon64 3700+ utilisant environ 250 Mo de mémoire) ce qui est plutôt bon, mais seulement pour Windows et 2.1.1 pour le moment. L'éditeur de liens interne ouvre aussi la porte à des liaisons intelligentes plus avancées qui demande des connaissances spếcifiques à Pascal, comme abandonner une méthode virtuelle (20 % sur la taille du code des exemples Lazarus, 5 % sur l'EDI Lazarus en première estimation grossière), et traitant mieux les cjaîbne des ressource inutilisées. Tout ceci est en alpha, et les statistiques du dessus sont probablement trop optimistes, puisque Lazarus ne travaille pas encore avec ces optimisations.

Pendant une discussion sur Stack Overflow, certains détails extra viennent en avant (et la plupart les mêmes pour FPC comme pour Delphi, au moins sous Windows) :

Sections initialization et finalization

Si vous incluez une unité en section USES, même quand il s'agit de USES indirects à travers une unité différente, alors SI l'unité contient des sections initialization ou finalization, ce code et ses dépendances sont toujours liés.

Une unité pour laquelle c'est important est sysutils. Conformément à la compatibilité Delphi, sysutils convertit les erreurs d'exécution en exceptions avec un message textuel. Toutes les chaînes de sysutils réunies sont un peu volumineuses, il n'y a rien qui puisse être fait contre cela, à part de retirer un paquet d'initialisations de sysutils qui la rendra incompatible avc Delphi. C'est donc plus une chose pour une version embarquée, si une telle équipe se portait volontaire.

Binaires statiques

(main article: Lazarus/FPC Libraries)

On peut aussi faire des binaires totalement statiques sur chaque système d'exploitation, en incorporant toutes les bibliothèques dans le binaire. Cela est fait en général pour faciliter le déploiement, mais cela produit par là-même d'énormes binaires. Puisqu'il s'agit du "territoire des sorciers" (wizard territory), je ne le mentionne que par souci d'exhaustivité. Les personnes qui font cela le font en connaissance de cause, nous l'espèrons.

Au lieu de produire des binaires statiques, des programmeurs font de la liaison dynamique / partagée. Cela PEUT générer un binaire exécutable beaucoup, beaucoup plus petit. Pourtant, il existe des cas où le binaire devient plus gros, en particulier sur des architectures comme x86_64 où le PIC est activé par défaut. La liaison dynamique (Win32) et la liaison partagée (*nix) sont le même concept, mais leur fonctionnement en interne est différent, comm cela peut être vu par le fait que les systèmes *nix ont besoin des bibliothèques partagées sur l'hôte pour faire le lien (croisé), alors que pour lier un binaire Windows vous n'avez pas besoin des DLLs nécessaires sur le système.

Optimisation

L'optimisation peut également réduire un peu la taille du code. Le code optimisé est généralement plus serré (mais seulement en dixième de pourcent). Assurez-vous d'utliser l'option -O3. Voir aussi Optimisation globale de programme pour davantage de réduction de la taille du code.

Fichier lpr de Lazarus

Dans Lazarus, si vous ajoutez un paquet à votre projet/fiche, vous obtenez que l'enregistrement de son unité est ajouté au fichier lpr. Le fichier lpr n'est normalement pas ouvert. Si vous voulez l'éditer, vous l'ouvrez d'abord (via Projet|Voir le code source du projet). Ensuite vous retirez toutes les unités non nécessaires telles que les interfaces, les fiches, les seules fiches requises sont vos propres unités de fiches, toutes les autres choses ne sont pas nécessaires mais vous devez vous assurez de ne pas supprimer d'unité qui enregistre des choses telles que des lecteurs d'images (jpeg) ou des cas de test. (Ndt: C'est cependant un exercice risqué car cela supposerait de connaître l'évolution future des unités utilisées)

Vous économisez alors des mégaoctets ET quelques dépendance en liaison aussi si vous utilisez des gros paquets (tels que glscene).

Ce type de comportement est typique pour les bibliothèques qui font beaucoup de section d'initialisation d'unités. Remarquez que peu importe où elles sont utilisées (lpr ou unité normale). Bien sûr, la liaison intelligente essaie de minimiser ces effets.

Problèmes 2.2.0

(non traduit car sans doute obsolète bien que non vérifié) There appear to be some size problems in FPC 2.2.0 is this still relevant for 2.6.x/2.7.x? Note that these remarks hold for the default setup with internal linker enabled.

  • It seems that FPC 2.2.0 doesn't strip if any -g option is used to compile the main program. This contrary to earlier versions where -Xs had priority over -g
  • It seems that FPC 2.2.0 doesn't always smartlink when crosscompiling. This can be problematic when compiling for windows, not only because of size, but also because dependencies are created to functions that might not exist.

UPX

(non traduit, version 2.6 trop ancienne) Note: UPX support in makefiles, and the distribution of upx by FPC ceased after 2.6.0. New releases of FPC won't package upx any more

The whole strange UPX cult originates mostly from a mindless pursuit of minimal binary sizes. In reality UPX is a tool with advantages and disadvantages.

The advantages are:

  1. The decompression is easy for the user because it is self-contained
  2. Some size savings are made if (and only if) the size criterion is based on the binary size itself (as happens in demo contests). However, especially in the lowest classes it might be worthwhile to minimize the RTL manually and to code your compression yourself, because you can probably get the decompression code much tighter for binaries that don't stress all aspects of the binary format.
  3. For rarely used applications or applications run from removable media the disk space saving may outweigh the performance/memory penalties.

The disadvantages are:

  1. worse compression (and also the decompression engine must be factored into _EACH_ binary) by archivers (like ZIP) and setup creation tools
  2. decompression occurs on every execution, which introduces a startup delay.
  3. Since Windows XP and later now feature a built-in decompressor for ZIP, the whole point of SFX goes away a bit.
  4. UPXed binaries are increasingly being fingered by the malware heuristics of popular antivirus and mail-filtering apps.
  5. An internally compressed binary can't be memorymapped by the OS, and must be loaded in its entirety. This means that the entire binary size is loaded into VM space (memory+swap), including resources.
  6. You introduce another component (UPX, decompression stub) that can cause incompatibilities and problems.

The memorymapping point needs some explanation: With normal binaries under Windows, all unused code remains in the .EXE, which is why Windows binaries are locked while running. Code is paged in 4k (8k on 64-bit) at a time as needed, and under low memory conditions is simply discarded (because it can be reloaded from the binary at any time). This also applies to graphic and string resources.

A compressed binary must usually be decompressed in its entirety, to avoid badly affecting the compression ratio. So Windows has to decompress the whole binary on startup, and page the unused pages to the system swap, where they rot unused, and also take up extra swap space.

Coûts de cadre d'application (Framework)

Un cadre d'application (ou cadriciel) réduit grandement la quantité de travail pour développer une application.

Cela a cependant un coût, car un framework n'est pas une simple bibliothèque, mais plutôt un sous-système entier qui traite de l'interfaçage avec le monde extérieur. Un framework est conçu pour un ensemble d'applications qui peuvent accéder à de nombreuses fonctionnalités (même si une seule application ne le peut pas).

Cependant, plus un framework peut accéder à des fonctionnalités, plus un certain sous-ensemble minimal devient grand. Pensze à l'internationalisation, au support des ressources, aux environnements de traduction (traduction sans recompilation), messages d'erreur siginificatifs pour les exceptions de base. Tout ceci est appelé les frais généraux du cadre d'application (framework overhead).

La taille d'une application vide n'est pas due aux inefficiences du compilateur mais aux frais généraux du cadre d'application. Le compilateur ôtera le code inutilisé automatiquement, mais tout le code ne peut pas l'être. La conception du cadre d'application détermine quel code le compilateur est capable d'enlever lors de la compilation.

Certains cadre d'application sont à l'origine de très petits frais généraux, alors que d'autres en amènent de plus gros. Tailles attendues pour les applications vides sur des cadriciels bien connus:

  • Aucun cadriciel (seulement la RTL): +/- 25kb
  • Aucun cadriciel (RTL+sysutils seulement): +/- 100-125kb
  • MSEGUI: +/- 600kb
  • Lazarus LCL: +/- 1000kb
  • Free Vision: +/- 100kb
  • Key Objects Library: +/- 50kb

En bref, choisissez bien votre cadriciel. Un cadriciel puissant peut vous faire économiser beaucoup de temps, mais si l'espace est compté (cas du code embarqué), un cadriciel plus petit pourrait être un meilleur choix. Mais assurez d'avoir besoin de ce gain de place. De nombreux amateurs choisissent par habitude le plus petit cadriciel et finissent avec du code immaintenable puis arrêtent. Ce n'est pas drôle de maintenir des applications dans de multiples cadriciels pour gagner quelques ko.

Remarquez par exemple que le cadriciel de Lazarus est relativement lourd du fait de l'utilisation de la RTTI et de l'introspection pour ses mécanismes de flux, et pas seulement la taille du source. la RTTI rend plus de code accessible en dégradant les performances de la liaison intelligente.

Attentes irréalistes

Beaucoup de gens regardent la taille d'un binaire et s'écrient Gonflé!. Quand vous tentez d'argumenter avec eux, ils se cachent derrière des comparaisons (mais TP produit ...), ils ne disent jamais réellement 'pourquoi' ils sont besoin d'un binaire qui soit plus faibles sur tous les coûts. Certains d'entre eux ne réalisent même pas qu'un code 32-bit (maintenant 64-bit) est TOUJOURS plus gros qu'un code 16-bit (maintenant 32-bit) ou que l'indépendance à un SE a un coût ou ..., ou ..., ou ...

Comme dit plus haut, avec la taille actuelle des disques durs, il n'y a pas de raison de garder les binaires avec des tailles très petites. les binaires FPC étant 10, 50 ou même 100% plus grands que ceux des compilateurs du précédent millénaire ne devraient pas avoir beaucoup d'importance. Un bon indicateur de ces visions est le sur-emploi franchement émotionnel et infondé d'UPX (voir au dessus), qui est un signe de la folie de la taille du binaire, puisque cela n'a pas de sens techniquement parlant.

Alors d'où vient cette émotion ? S'agit-il simplement de résister au changement ou d'être des maniaques de contrôle ? Je n'ai jamais vu beaucoup de cause justifiée, sauf que parfois certains d'entre eux poussaient leurs propres bibliothèques inférieures et essayaient de gagner du terrain contre des bibliothèques bien établies basées sur des arguments de taille. Mais cela n'explique pas tous les cas, donc je pense que la taille binaire est vraiment le dernier artefact "640k devrait être suffisant pour n'importe qui" (Ndt: citation de Bill Gates). Même si ce n'est pas réel, mais juste mental.

Une fausse révélation pour cela est que le nombre de correctifs réalistes dans ce domaine est proche de zéro, sinon zéro. Ce sont uniquement des discussions maillist, et des mods RTL triviaux qui ne gagnent presque rien et qui entravent sérieusement la création de vraies applications et la compatibilité (et je ne suis pas un maniaque de la compatibilité pour commencer). Personne ne s'assoit pendant quelques jours et fait une enquête approfondie et propose des correctifs. Il n'y a pas de RTL réduite entretenue en externe, pas de jeux de correctifs, etc., alors que ce serait extrêmement facile. D'une manière ou d'une autre, les gens ne sont après le dernier octet que si c'est facile à réaliser, ou s'ils ont quelque chose de "moins gonflé" à promouvoir.

Light bulb  Remarque: le paragraphe ci-dessus est toujours vrai, près de cinq ans après sa rédaction.

Quoi qu'il en soit, les quelques personnes embarquées que je connais qui utilisent FPC de manière intensive ont toutes leurs propres bibliothèques personnalisées. Pour une personne, l'internationalisation compte même lorsqu'elle est intégrée (car elle parle une langue avec des accents), et les exceptions ne comptent pas, pour quelqu'un d'autre, les exigences sont encore différentes. Chacun a ses propres compromis et choix, et si l'espace est «vraiment» restreint, vous ne faites pas de compromis pour utiliser la distribution générale.

Et oui, FPC pourrait utiliser quelques améliorations ici et là. Mais ceux-ci ne devraient pas nuire à la «programmation générale», à la nature multiplateforme du FPC, à la facilité d'utilisation et à être réaliste dans les besoins en main-d'œuvre. Les choses complexes prennent du temps. Les optimiseurs globaux ne tombent pas du ciel facilement

Comparaisons avec GCC

Les comparaisons avec GCC sont un peu moins irréalistes. Même les développeurs se reflètent (et FPC) régulièrement dans GCC. Bien sûr, GCC est un monstre sponsorisé par une entreprise, qui est également le favori mondial de l'Open Source. Toutes les comparaisons ne sont pas raisonnables ou équitables. Même les compilateurs qui se basent sur GCC ne supportent pas toutes les fonctionnalités "c" de gcc fortement sponsorisées.

Néanmoins, compte tenu des différences de taille des projets, FPC fait un travail étonnamment bon. La vitesse est correcte, sauf peut-être pour certains cas de calcul fortement scientifique, les tailles binaires et l'utilisation de la mémoire sont suffisantes voire meilleures en général, le nombre de plates-formes ne déçoit pas (même s'il est dommage qu'il manque de 'vraies' cibles embarquées).

Un autre problème ici est que FreePascal lie généralement statiquement (car il n'est pas ABI stable et il est peu probable qu'il soit déjà sur le système cible même s'il l'était) son propre RTL. GCC établit des liens dynamiques avec les bibliothèques système. Cela fait que les très petits programmes (en termes de taille de source) créés avec fpc ont des binaires beaucoup plus grands que ceux créés avec GCC. Il convient de mentionner ici que la taille binaire n'a rien à voir avec l'empreinte mémoire du programme. FPC est généralement bien meilleur à cet égard que GCC.

Pourtant, je pense que compte tenu des ressources, FPC se porte extraordinairement bien.

Comparaisons avec Delphi

Dans les comparaisons avec Delphi, il faut garder à l'esprit que la conception de Delphi 32 bits provient de la période où beaucoup de gens n'avaient même pas de Pentium-I, et le développeur qui avait 32 Mo de RAM était chanceux. De plus, Delphi n'a pas été conçu pour être portable.

Compte tenu de cela, Delphi a assez bien évolué, bien qu'il y ait toujours place à l'amélioration et à des réajustements qui corrigent les problèmes historiques et les compromis. (C'est un fait assez bien connu que beaucoup de routines d'assembleur dans les plus récents Delphi étaient plus lentes que leurs équivalents Pascal, car elles n'ont jamais été mises à jour pour les processeurs plus récents. On dit que cela n'a été corrigé que depuis Delphi 2006.)

Pourtant, lentement sur le front du compilateur, FPC n'est plus le pauvre cousin de Delphi. Les comparaisons sont frontales, et le gain de FPC 2.1.1 sur Delphi devient lentement la règle, et non plus l'exception.

Bien sûr, ce n'est que le compilateur de base. Dans d'autres domaines, il y a encore assez de travail à faire, bien que l'éditeur de liens interne aide beaucoup. Le débogueur ne sera pas amusant cependant :-) Aussi dans l'interopérabilité des langages (C ++, Obj C, JNI) et les bibliothèques partagées, il y a beaucoup de travail à faire, même dans le système de base.

Comparaisons avec .NET/Java

Soyez très prudent dans les comparaisons avec ces systèmes compilés JIT: les programmes JIT-é ont des caractéristiques de référence différentes, et l'extrapolation des résultats des benchmarks aux programmes complets est également différente.

Alors qu'un JIT peut parfois faire un excellent travail (en particulier dans les petits programmes qui consistent principalement en une seule boucle serrée), mais ce bon résultat ne s'adapte souvent pas. Dans l'ensemble, mon expérience est que le code compilé statiquement est généralement plus rapide dans la plupart des codes qui ne sont pas principalement liés par une boucle serrée hautement optimisable, malgré les nombreuses affirmations sur le net.

Une source quantitative assez intéressante pour cela est cette entrée Shootout faq. Une autre intéressante est memory allocation in JVM/.NET.

Notez que depuis 2007, Java 6 a soudainement provoqué un saut significatif dans les évaluations de fusillade Java (Java shootout-ratings), et commence à toucher le fond des compilateurs natifs normaux. Cela montre qu'il faut être très prudent en faisant écho aux sentiments sur le Web (à la fois positifs et négatifs) et s'en tenir à sa propre mesure, avec les conditions aux limites ajustées au domaine d'application dans lequel vous vous trouvez.

Analyse de diverses options

Tests sur Lazarus 0.9.29 avec FPC 2.4 (FPC 2.2.4 sous Windows).

Compilateur optimisé signifie:

  • 1. Projet|Options du projet...|Options du compilateur|Compilation et édition de liens|Lien intelligent (-CX) -> Coché
  • 2. Projet|Options du projet...|Options du compilateur|Débogage| Décocher tout sauf 'Eliminer les symboles de l'exécutable Strip' (-Xs) -> Coché
  • 3. Projet|Options du projet...|Options du compilateur|Compilation et édition de liens|Lier intelligemment (-XX) -> Coché

Le point le plus important semble être le 2. Pour une simple application la taille de lexécutable serait de 1-3 Mo au lieu de 15-20 Mo.

  • 4. (facultatif) Projet|Options du projet...|Options du compilateur|Compilation et édition de liens|Plus petit plutôt que plus rapide (-Os) -> Coché (Avertissement: cela peut diminuer les performances en vitesse d'exécution).


Lazarus par défaut signifie comme installé depuis le setup.

LCL sans information de débogage signifie après reconstruction de lk'IDE Lazarus et de la LCL sans information de débogage (-g-).

    Lazarus par défaut     LCL sans information de débogage
Ubuntu 64 bits / Lazarus 64 bits
Application par défaut     13,4  Mb     7,5 Mb / 8
Compilateur optimisé     4,4 Mb     2,70 Mb (0.29svn FPC2.4 2,5)
   
Ubuntu 32 bits / Lazarus 32 bits
Application par défaut     19,6  Mb     5,7 Mb
Compilateur optimisé     2,9 Mb     1,6 Mb
   
Windows XP 32 bits / Lazarus 32 bits
Application par défaut     11,8 Mb     2,14 Mb
Compilateur optimisé     1,62 Mb     1,50 Mb
   
Windows Seven 64 bits / Lazarus 64 bits
Application par défaut     12,3  Mb     3,20 Mb
Compilateur optimisé     2,14 Mb     2,16 Mb

Voir aussi

https://wiki.freepascal.org/