代码之家  ›  专栏  ›  技术社区  ›  Qwertie

有“函数大小分析器”吗?

  •  13
  • Qwertie  · 技术社区  · 16 年前

    在C++项目上工作了三年之后,可执行文件已经增长到4 MB。我想看看这些空间都到哪里去了。有没有一个工具可以报告最大的太空霸主是什么?按类(类中的所有函数)、按模板(所有实例化)和按库(有多少属于C标准库和STL?exe中的每个库有多少?)

    编辑:注意,我在Windows上使用Visual C++。

    5 回复  |  直到 16 年前
        1
  •  16
  •   Todd Gamblin    16 年前

    ,你可以使用 nm 要显示可执行文件中的所有符号并按大小按相反顺序排序,请执行以下操作:

    $ nm -CSr --size-sort <exe>
    

    选项:

    • -C
    • -S 显示符号的大小。
    • --size-sort 按大小对符号进行排序。
    • -r 与排序相反。

    如果希望获得每个命名空间或每个类的结果,可以 grep '的输出 namespace:: ', ' namespace::class_name:: ', .

    如果只想查看已定义的符号 在里面 然后添加可执行文件(不是在其他地方定义的文件,如库中定义的文件) --defined-only . 不过,按大小排序应该考虑到这一点,因为未定义的符号不会有大小。

    窗户 ,您应该仍然能够使用 纳米 在你的二进制文件上,因为 纳米 COFF 二进制文件。您可以安装 纳米 通过cygwin,或者您可以将windows可执行文件复制到linux框并运行 纳米

    dumpbin ,它在Windows上转储有关二进制文件的信息。您可以使用获取有关符号的信息 /SYMBOLS 开关,但它看起来并没有直接提供有关其大小的信息。

        2
  •  7
  •   Crashworks    16 年前

    在Windows中的Visual Studio compiles下,此信息位于.map文件中(位于.pdb附近)。

    补充 undname.exe VisualStudio附带的实用程序。它接受命令行上的单个名称,或者您可以向它提供一个.map文件。

    例如

    Microsoft (R) C++ Name Undecorator
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    Undecoration of "?push_back@?$mini_vector@U?$Point@U?$FixedPoint@$0O@H@Math@@@Math@@$05@@QAAXABU?$Point@U?$FixedPoint@$0O@H@Math@@@Math@@@Z" is 
    
    "public: void __cdecl mini_vector<struct Math::Point<struct Math::FixedPoint<14,int> >,6>::push_back(struct Math::Point<struct Math::FixedPoint<14,int> > const &)"
    
        3
  •  2
  •   tinman    13 年前

    我找不到 nm 为我工作,但确实找到了一个有用的工具,名为 Sizer . 它读取VisualStudio使用调试接口访问库创建的调试信息。正如网站上描述的那样,它的使用非常简单。

    1. 使用程序数据库(.pdb)文件中的调试信息编译
    2. 从命令行运行sizer,例如。 Sizer.exe <path-to-exe-file> . 输出将转到标准输出,因此您可能需要重定向到文件。

    代码大小按不同的部分进行分解,并按函数、数据、类等进行分组,每个部分按代码大小的降序排序。

        4
  •  1
  •   Michael    16 年前

        5
  •  1
  •   Mike Dunlavey    16 年前

    获取链接地图,或使用 dumpbin 获取符号和大小的列表。

    很可能有很多你并不需要的东西被拉进来了。

    补充:你得到满意的答案了吗?我意识到人们有两种方式来处理这样的问题:

    • 在他们做任何事情之前先测量一下。
    • 只要找到他们不需要的大东西,把它撕下来,然后重复,直到他们不需要为止。

    就我个人而言,我更喜欢后者——它能更快地得到结果。

    你说这个应用是4MB。假设真正需要的大小是1MB(或一些这样的大小)。这意味着,如果您从映射文件中随机选择一个例程,它有75%可能是您不需要的。找出是什么导致它被包括在内,看看你是否真的需要它。

    在您给出的示例中,您看到了一个包装独立于设备的位图的类。您可以在应用程序中找到该类的实例,并可能将其替换为基本WIN32位图。它可能不那么漂亮,但可以节省大量的应用程序大小。

    然后继续做下去。你扔掉的每一大块都会使剩下的部分在应用程序中占据更大的比例,因为应用程序已经缩小了,但这些部分没有缩小。这使它们更容易在地图文件中找到。