如何确定为什么我的库中的文本大小如此之大
How to determine why text size in my library is so huge?
我有一个使用 Android NDK for ARM 构建的共享库文件。里面还有一点JNI。这个SO文件链接到许多其他.a文件(我们自己的静态库,我们作为依赖项构建)以及其他一些第三方静态库,如boost。
我正在使用GCC 4.8并使用具有C++11功能的STL。
我对此做了一些自我研究。特别是,我遇到了这个线程:
为什么我的C++输出可执行文件这么大?
这帮助我想出了一些要运行的命令,例如size
:
$ size libmine.so
text data bss dec hex filename
13017993 201972 54120 13274085 ca8be5 libmine.so
不幸的是,除了要运行的命令之外,链接的 SO 问题在诊断方面对我没有多大帮助(或者也许我只是在 Linux 风格的开发方面没有足够的经验来可靠地使用这些信息)。我不确定如何分析产生的结果,以帮助我查明导致任何增长的代码、特定库或模板函数/类/等区域。
共享库本身是13MB,这是相当巨大的。我确实验证了我的.SO文件被"剥离",我想这意味着没有调试符号。在这一点上,我不确定这是由于提升还是一些疯狂的模板实例化。如何确定是什么促成了共享图书馆的大规模增长?
我没有答案。还。只是分享我的快速和肮脏的单行本,所以你不必这样做。免責聲明性能很糟糕,但足够™好。
Perl/Python/Haskell/...应该使用的实用主义是关键词。您需要安装
bc
才能进行求和¹
从 Andy Brown 的评论开始,我分析了我自己项目的二进制文件:
-
定义一个帮助程序函数来列出名称:
function names() { nm -l -S --size-sort --radix=d -C "$@"; }
删除
-l
(行号)以提高性能(我不需要) -
以下单行显示重复的累积大小:
for a in bin/*; do echo -e "$at$(names "$a" | cut -d -f1-2 | sort | uniq -cd | perl -ne '@a=split and print "" . (($a[0]-1) * $a[2]) . "n"' | paste -sd+ | bc)"; done
这往往只显示弱符号。因为这里的实际值是重复的,我不确定这是否意味着重复的大小计入剥离的二进制文件大小
-
符号类型的直方图:
for a in bin/*; do names "$a" | awk '{print $3}'; done | sort | uniq -c | sort -rn
按符号 类型划分的符号总大小,按上一步直方图频率降序排列:
for a in bin/*; do names "$a" | awk '{print $3}'; done | sort | uniq -c | sort -rn | while read count type do total=0 for a in bin/* do size=$(names "$a" | awk "$3=="$type" {print $2}" | paste -sd+ | bc) total=$(($total + $size)) echo -e "$typet$sizet$a" done echo -e "total:t$totalttotal bytes in $count symbolsn-------" done
我的系统上的示例输出:
bin/tool1 208148
bin/liba.so 204463
bin/libcryptopp.so 166771
bin/tool2 211916
bin/tool3 204733
bin/testrunner 208271
46935 W
16173 V
10442 T
1724 u
574 d
184 R
158 B
94 t
49 r
33 b
13 D
W 1053961 bin/tool1
W 1030888 bin/liba.so
W 784518 bin/libcryptopp.so
W 1097729 bin/tool2
W 1031444 bin/tool3
W 1072752 bin/testrunner
total: 6071292 total bytes in 46935 symbols
-------
V 317146 bin/tool1
V 243869 bin/liba.so
V 368815 bin/libcryptopp.so
V 321841 bin/tool2
V 316629 bin/tool3
V 316947 bin/testrunner
total: 1885247 total bytes in 16173 symbols
-------
T 459075 bin/tool1
T 449020 bin/liba.so
T 610503 bin/libcryptopp.so
T 455224 bin/tool2
T 450630 bin/tool3
T 449234 bin/testrunner
total: 2873686 total bytes in 10442 symbols
-------
u 4912 bin/tool1
u 4136 bin/liba.so
u 448 bin/libcryptopp.so
u 5381 bin/tool2
u 4136 bin/tool3
u 4136 bin/testrunner
total: 23149 total bytes in 1724 symbols
-------
¹ 我知道这可以通过纯 bash 来完成,但它要么涉及在评估扩展中扩展整个流,要么涉及编写更多嵌套循环。我更喜欢bc
这里。
- 文本文件中的单词链表
- 从命令行c++发送文本文件名
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 2D数组来自文本输入,中间有空格
- 为什么堆栈和堆在内存中分离得如此之多?
- 为什么 Lisp 中 1000 阶乘的计算如此之快(并显示正确的结果)?
- 为什么C++线程/未来开销如此之大
- 为什么"quick sorting"算法的这两种变体在性能上差异如此之大?
- 为什么整数的垃圾价值如此之大
- Python vs CPP:为什么速度差异如此之大
- C++-为什么标记化器从文件中读取行的速度如此之慢
- 如何确定为什么我的库中的文本大小如此之大
- 为什么在使用std::bind和lambda时生成的对象如此之大
- 为什么从内存映射文件中读取速度如此之快
- 为什么我的C++程序在从长double切换到float128时速度如此之慢
- 为什么可执行文件在使用静态库编译后会增长如此之多
- 为什么ucontext的开销如此之高
- 为什么分配数组后的堆如此之大?
- Win32 resource.hpp为什么资源ID如此之高
- 如何找出为什么我的DLL增长如此之快