Why are applications so large? [closed]
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years a开发者_如何转开发go.
Improve this questionI 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.
精彩评论