为什么应用程序如此之大?

时间:2011-10-13 22:29:40

标签: c++ size storage

我制作了一个复杂的手部检测软件,总共只有大约28KB的存储空间。我有大约600行代码,只有28KB。其他软件程序如何变得如此之大(即几千兆字节)。我的意思是我理解为什么游戏很大,但几天前我发现了一个大约50MB的简单图片浏览器。它是如何设法占用这么多空间的?我正在考虑存储而不是RAM

我基本上想知道的是程序如何设法需要这么多的存储空间?

5 个答案:

答案 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产品,他们在减少二进制大小方面有很多技巧,充分利用二进制文件中的每个字节。