我制作了一个复杂的手部检测软件,总共只有大约28KB的存储空间。我有大约600行代码,只有28KB。其他软件程序如何变得如此之大(即几千兆字节)。我的意思是我理解为什么游戏很大,但几天前我发现了一个大约50MB的简单图片浏览器。它是如何设法占用这么多空间的?我正在考虑存储而不是RAM
我基本上想知道的是程序如何设法需要这么多的存储空间?
答案 0 :(得分:4)
我有大约600行代码,只有28KB
600 LOC是 tiny 应用程序。复杂性无关紧要。此外,某些优化可以使“更大”但运行速度更快的代码。最重要的是,可执行文件可能有许多直接编译到其中的资源,即图像。一个小的,主要是算法的命令行实用程序并不是那里唯一的应用程序类型。
以我每天开发的应用程序为例。这个项目有1,000,000多行代码,更不用说编译到其中的所有静态库代码了。
答案 1 :(得分:4)
这取决于 - 他们的成就,程序员的效率,以及最重要的资源。你的手检测程序可能主要是算法,对吧?常见的软件可能包括诸如本地化之类的东西(我知道Notepad ++的巨大尺寸主要归功于它的72种或某些语言以及带图像的各种帮助文件)以及图标,大图像,闪屏,定制设计形式......它们也可能用.NET或其他东西编写,这是IL,包括版本检查代码和东西......列表一直在继续。
某些应用程序可能还包括它们自己打包使用的库,以避免“丢失DLL”消息,或者它们可能包含静态库,并且可能包含字体或类似的东西。
有很多不同的可能性。
答案 2 :(得分:4)
您的应用程序非常小,因为您使用dynamically linked libraries并严重依赖其他人提供的库来完成大部分处理。
让我们考虑一下我最喜欢的图片浏览器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
它相当小,但这是因为它协调了许多动态库的操作:
$ 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)
如果我们查看所有这些库的大小,我们会发现实际上该程序是 huge ,但基于功能分为几十个:
$ 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)
这是十兆字节的库。当然,并非所有的库都将被使用,但这是10兆字节的代码,未包含在可执行文件中。我认为你的应用程序是相似的 - 看一下你的应用程序需要的库的大小,你也可以更好地理解你所写的内容的大小。
但是,当您看到巨大的可执行文件时,开发人员经常选择statically link their libraries - 这意味着它们是自包含的可执行文件,并且不依赖于系统提供任何可执行文件特定图书馆。这将所有库中使用的所有例程拖入主可执行文件中,这大大“增长”了特定的可执行文件 - 在某种意义上,它是一个更好的指示程序的大小。
另一个影响因素是简单bloat - 如果开发人员选择了错误的数据结构,则可能导致过多的代码处理格式更改,或者出现复杂的解析/格式化问题,或者在以下情况下使用过于通用的代码更具体的代码可能更小。
可能很难理解“代码臃肿”,但一个好的第一个解释可能是Joel's article on Leaky Abstractions。但我们都能看到效果:我们的处理器比二十年前快几百倍,但许多“常用程序”比二十年前大得多,我们的应用程序运行速度大致相同。有没有看到在“现代”系统上运行的Windows 3.1?它的速度非常快,但没有任何用户期望从图形工作环境中获得的neato半透明效果。
答案 3 :(得分:2)
Static linking可以通过直接在最终二进制文件中包含库代码来引入代码膨胀。
答案 4 :(得分:1)
您的应用程序大小约为28kB并不奇怪,这可能是因为您的构建环境将标准C / C ++库链接到应用程序中。为了解决这个问题,您可以将这些库排除在与您的应用程序链接之外,但您必须提供它们提供的最简单的功能。
查看4K demoscene产品,他们在减少二进制大小方面有很多技巧,充分利用二进制文件中的每个字节。