开发者

Why are applications so large? [closed]

Closed. This question is off-topic. It is not currently accepting answers.

Want to improve this question? Update the question so it's on-topic for Stack Overflow.

Closed 11 years a开发者_如何转开发go.

Improve this question

I made a complex hand detection software and it totals only around 28KB storage. I have around 600 lines of code and only have 28KB. How do other software programs manage to get so big (i.e. couple of Gigabytes). I mean I understand why games are big, but I couple of days ago I found a simple picture viewer that was around 50MB. How did it manage to take up so much space? I am taking about storage not RAM

What I am basically wondering is how do programs manage to need so much storage space?


It depends - what they were made with, how efficient the programmer was, and probably most importantly, the resources. Your hand detection program is probably mostly algorithms, right? Common software might include things such as localization (I know Notepad++'s huge size owes mostly to its 72-or-some languages and various help files with images) as well as icons, large images, splash screens, custom-designed forms... they also might be written in .NET or something, which is IL and includes version-checking code and things... the list goes on and on.

Some applications might also include the libraries they use packaged within themselves so as to avoid "missing DLL" messages, or they might have static libraries included, and maybe they package fonts or things like that.

There are lots of different possibilities.


I have around 600 lines of code and only have 28KB

600 LOC is a tiny application. Complexity is irrelevant. Also, certain optimizations can make for "larger" yet faster running code. On top of that, an executable may have many resources compiled directly into it, i.e., images. A small, mostly algorithmic command line utility is not the only type of application out there.

Take for example the application I develop on a daily basis. This project has 1,000,000+ lines of code, not to mention all of the static library code that gets compiled into it.


Your application is artificially small because you're using dynamically linked libraries and relying heavily on the libraries provided by others to do the bulk of your processing.

Lets consider my favorite image viewer, qiv:

$ ls -l /usr/bin/qiv
-rwxr-xr-x 1 root root 67048 2010-05-15 13:12 /usr/bin/qiv
$ size `which qiv`
   text    data     bss     dec     hex filename
  58586    4304    4968   67858   10912 /usr/bin/qiv

It's reasonably tiny, but that's because it orchestrates the actions of dozens of dynamic libraries:

$ ldd /usr/bin/qiv
    linux-vdso.so.1 =>  (0x00007fff2db9d000)
    libgdk-x11-2.0.so.0 => /usr/lib/libgdk-x11-2.0.so.0 (0x00007f7492ab3000)
    libgdk_pixbuf-2.0.so.0 => /usr/lib/libgdk_pixbuf-2.0.so.0 (0x00007f7492893000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f749260d000)
    libpangocairo-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 (0x00007f7492400000)
    libpango-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 (0x00007f74921b6000)
    libcairo.so.2 => /usr/lib/libcairo.so.2 (0x00007f7491ef4000)
    libgio-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 (0x00007f7491bc9000)
    libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007f7491978000)
    libgmodule-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007f7491773000)
    libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f749156e000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f7491366000)
    libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f7491076000)
    libImlib2.so.1 => /usr/lib/libImlib2.so.1 (0x00007f7490e0c000)
    libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f7490ad2000)
    libXinerama.so.1 => /usr/lib/x86_64-linux-gnu/libXinerama.so.1 (0x00007f74908ce000)
    libmagic.so.1 => /usr/lib/libmagic.so.1 (0x00007f74906b1000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7490493000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f74900fe000)
    libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f748fec8000)
    libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f748fcb6000)
    libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f748faaa000)
    libXi.so.6 => /usr/lib/x86_64-linux-gnu/libXi.so.6 (0x00007f748f89a000)
    libXrandr.so.2 => /usr/lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007f748f691000)
    libXcursor.so.1 => /usr/lib/x86_64-linux-gnu/libXcursor.so.1 (0x00007f748f486000)
    libXcomposite.so.1 => /usr/lib/x86_64-linux-gnu/libXcomposite.so.1 (0x00007f748f283000)
    libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f748f080000)
    libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f748ee79000)
    libpangoft2-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 (0x00007f748ec4d000)
    libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f748e9b3000)
    libpixman-1.so.0 => /usr/lib/libpixman-1.so.0 (0x00007f748e745000)
    libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f748e51d000)
    libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007f748e31a000)
    libxcb-render.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-render.so.0 (0x00007f748e111000)
    libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f748def5000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f748dcdc000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f748dad8000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f748d89c000)
    libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f748d680000)
    libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f748d462000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f7492d8b000)
    libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f748d237000)
    libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f748d034000)
    libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f748ce2d000)

If we look at the sizes of all those libraries, we see that actually the program is huge, but broken into dozens of pieces based on functionality:

$ size -t `ldd /usr/bin/qiv | awk '/=> \// {print $3;}'`
   text    data     bss     dec     hex filename
 710482   18672    1296  730450   b2552 /usr/lib/libgdk-x11-2.0.so.0
 122635    2448     384  125467   1ea1b /usr/lib/libgdk_pixbuf-2.0.so.0
 537611     804      72  538487   83777 /lib/x86_64-linux-gnu/libm.so.6
  44015    2056     176   46247    b4a7 /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0
 287233    8948     672  296853   48795 /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0
 764734    8656   12552  785942   bfe16 /usr/lib/libcairo.so.2
1194267   19848    5936 1220051  129dd3 /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
 316566    5184    3336  325086   4f5de /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
   8761     824     152    9737    2609 /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0
  14097    1088      72   15257    3b99 /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0
  27388    1236    2536   31160    79b8 /lib/x86_64-linux-gnu/librt.so.1
 968533    3568    2280  974381   ede2d /lib/x86_64-linux-gnu/libglib-2.0.so.0
 344595    2340   83136  430071   68ff7 /usr/lib/libImlib2.so.1
1261924   17720    1864 1281508  138de4 /usr/lib/x86_64-linux-gnu/libX11.so.6
   5431     760      40    6231    1857 /usr/lib/x86_64-linux-gnu/libXinerama.so.1
 100837    2752    8776  112365   1b6ed /usr/lib/libmagic.so.1
  96934    1732   16776  115442   1c2f2 /lib/x86_64-linux-gnu/libpthread.so.0
1609087   18360   22104 1649551  192b8f /lib/x86_64-linux-gnu/libc.so.6
 210197    5624    1000  216821   34ef5 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1
  67157    2512     648   70317   112ad /usr/lib/x86_64-linux-gnu/libXext.so.6
  36158    1088      56   37302    91b6 /usr/lib/x86_64-linux-gnu/libXrender.so.1
  59386     936     256   60578    eca2 /usr/lib/x86_64-linux-gnu/libXi.so.6
  29276     856      40   30172    75dc /usr/lib/x86_64-linux-gnu/libXrandr.so.2
  33972     968      40   34980    88a4 /usr/lib/x86_64-linux-gnu/libXcursor.so.1
   6615     624      40    7279    1c6f /usr/lib/x86_64-linux-gnu/libXcomposite.so.1
   5780     664      40    6484    1954 /usr/lib/x86_64-linux-gnu/libXdamage.so.1
  18261     728      40   19029    4a55 /usr/lib/x86_64-linux-gnu/libXfixes.so.3
 172803    3192     416  176411   2b11b /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0
 598232   20768      16  619016   97208 /usr/lib/x86_64-linux-gnu/libfreetype.so.6
 424774   17652     704  443130   6c2fa /usr/lib/libpixman-1.so.0
 153551    1852      16  155419   25f1b /lib/x86_64-linux-gnu/libpng12.so.0
   4552     936      16    5504    1580 /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0
  26611    2544      16   29171    71f3 /usr/lib/x86_64-linux-gnu/libxcb-render.so.0
 106810    1208     176  108194   1a6a2 /usr/lib/x86_64-linux-gnu/libxcb.so.1
  90374    1320      16   91710   1663e /lib/x86_64-linux-gnu/libz.so.1
   7554     792     152    8498    2132 /lib/x86_64-linux-gnu/libdl.so.2
 237076    1032      24  238132   3a234 /lib/x86_64-linux-gnu/libpcre.so.3
  90932    3424   10328  104684   198ec /lib/x86_64-linux-gnu/libresolv.so.2
 111900    1564    4880  118344   1ce48 /lib/x86_64-linux-gnu/libselinux.so.1
 157434    8112      16  165562   286ba /lib/x86_64-linux-gnu/libexpat.so.1
   7153     712      32    7897    1ed9 /usr/lib/x86_64-linux-gnu/libXau.so.6
  16874     592      16   17482    444a /usr/lib/x86_64-linux-gnu/libXdmcp.so.6
11088562     196696  181144 11466402     aef6a2 (TOTALS)

That's ten megabytes of libraries. Of course, not all of each library is going to be used, but that is ten megabytes of code that wasn't included in the executable. I presume your application is similar -- look at the size of the libraries that your application requires, and you might better understand the size of what you've written, too.

But, when you see huge executables, quite often the developers have chosen to statically link their libraries -- which means they are self-contained executables and do not rely on the system to provide any specific library. This drags in all the routines used in all the libraries into the main executable, which drastically "grows" the specific executable -- and in some sense, is a much better indicator of the size of a program.

Another contributing factor is simple bloat -- if a developer chooses the wrong datastructures, it can lead to excessive code to handle format changes, or complex parsing / formatting problems, or overly generic code being used in situations where more specific code could be smaller.

It can be hard to understand the "code bloat", but a good first explanation might be Joel's article on Leaky Abstractions. But we can all see the effects: our processors are several hundred times faster than two decades ago but many of the "usual programs" are so much bigger than two decades ago that our applications are running at roughly the same speed. Ever see Windows 3.1 running on a "modern" system? It's impressively fast but doesn't have any of the neato translucent effects that users have come to expect from their graphical work environment.


Static linking can bring in code bloat by including library code directly in the final binary.


It is not surprising that your application size is around 28kB, it is probably because your build environment is linking the standard C/C++ libraries into the application. To get over this you could exclude these libraries from linking with your application, but you'd have to provide the even the simplest functionality they provide.

Check out the 4K demoscene productions, they have quite a few tricks down their sleeves for reducing binary sizes, making good use of every single byte in their binary.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜