1
FozillaMox 2023-03-25 19:44:24 +08:00 12
为什么「多复杂的算法编译后也不会有几十 MB 」?
|
2
weijancc 2023-03-25 20:11:18 +08:00
常见和不常见的视频格式 ffmpeg 都能转码, 你至少先了解下他的功能再说话吧?
|
4
placeholder 2023-03-25 21:47:26 +08:00 3
源码就在那儿,嫌大自己优化一下呗
|
5
tuwulin365 2023-03-25 22:16:36 +08:00
不是静态链接?
|
6
TJT 2023-03-25 22:21:19 +08:00 2
将近 150 万行代码,凭什么不能有几十 MB ?
|
7
learningman 2023-03-25 22:32:21 +08:00 via Android
说明你对体积没概念呗。
自己编译个带符号表的版本,扫一遍每个符号多大不就知道都是啥占体积了 |
8
learningman 2023-03-25 22:32:48 +08:00 via Android 1
你要是能给他优化一下,保持现有功能的同时两三兆,几十万人感谢你应该还是有的
|
9
0o0O0o0O0o 2023-03-25 22:32:55 +08:00
|
10
40EaE5uJO3Xt1VVa 2023-03-25 22:35:09 +08:00
@learningman #8 是几十亿人,ffmpeg 无处不在,每个人手机里或多或少 都有 app 的视频编码引用了 ffmpeg
|
11
learningman 2023-03-25 22:40:24 +08:00 via Android 1
@yanzhiling2001 用了而已,用户不知道,只有开发者会感谢他
|
12
MrKrabs 2023-03-25 22:40:55 +08:00
你说的也没问题,但是 ffmpeg 带了多种编解码器
|
13
yuzo555 2023-03-25 22:48:04 +08:00
运行一下:
ffmpeg -encoders ffmpeg -decoders 然后再想想标题的问题 |
14
1423 2023-03-25 22:49:11 +08:00 6
https://ffmpeg.org/pipermail/ffmpeg-user/2013-February/013313.html
https://stackoverflow.com/questions/22898112/why-my-ffmpeg-libs-are-so-large 好问题果然是早就有人问过的 可以按上面的自己编译试试 不知道 28 原理是否适用,20%用不到的功能站了 80%的空间 |
15
kenvix 2023-03-25 22:49:19 +08:00
因为 ffmpeg 确实有很多屎山,建议你去重构它
|
16
yfwo 2023-03-26 01:24:42 +08:00
--disable-debug
|
17
dobelee 2023-03-26 01:40:26 +08:00
几十 MB 很大?
|
18
jevonszmx 2023-03-26 01:54:28 +08:00
@dobelee 赞同你,现在随便打开一个手机 app 都是百兆上 G 的,QQ 为了 qq 秀都是上 G 往里塞,结果大家反而为了几十 MB 折腾自己人,关键你辛辛苦苦搞了很久,别人甚至都感觉不到。
|
19
yfwo 2023-03-26 02:05:42 +08:00
@jevonszmx 嗯嗯,国内有 qq ,国外有 Gmail ,一个邮箱 app 没啥功能就 447 MB ( iOS App Store ),简直无厘头。
|
20
em70 2023-03-26 03:48:37 +08:00
大是因为编译时候带了太多功能,比如 png,aac,h265 等等,你可以根据自己业务编译一个不到 2M 的啊
|
21
talkischeap567 2023-03-26 05:10:08 +08:00
反串?
|
22
talkischeap567 2023-03-26 05:12:22 +08:00
为什么 windows 的体积会这么大?多复杂的系统编译后也不会有几十个 G 吧?
为什么 ios 的体积会这么大?多复杂的手机系统编译后也不会有 10 个 G 吧? |
23
billccn 2023-03-26 05:18:12 +08:00 5
用静态语言编写的追求高性能的代码编译结果大是很正常的,因为最基本的优化方向就是针对不同的情况有专门的代码。比如:
* 针对不同的指令集(各种版本的 SIMD)分别生成代码 * 针对某些数据类型进行特定的优化 * 依赖查表而不是运算 * 循环 unrolling * 为了减少跳转而把越来越多的函数 inline * 利用条件运算减少分支 这些叠加在一起还会形成 combinatorial explosion. 说笼统一点就是空间换时间的思路。 |
24
msg7086 2023-03-26 07:10:04 +08:00
但凡你知道很多代码为不同指令集分别做了优化并且运行时自动选择最优路径导致编译出来的二进制体积成倍增长也不至于嫌他大(
一般人用 ffmpeg 完全可以裁剪出自己需要的功能。比如我之前发布的一个软件,用到了 m2ts 解包功能,ffmpeg 裁剪到只需要支持 file protocol 和 mpegts demuxer ,出来只有几百 KB 。 |
25
msg7086 2023-03-26 07:15:17 +08:00
运行一下下面这些命令再看看你觉得多大容量比较合适。
ffmpeg -codecs ffmpeg -formats ffmpeg -muxers ffmpeg -demuxers ffmpeg -protocols ffmpeg -filters |
26
msg7086 2023-03-26 07:19:23 +08:00
另外再说说规模问题。
ffmpeg 里用到的 x265 ,他里面源码中最核心的那些汇编文件,光 x86 指令集,就有 20 多万行。这没算其他的指令集,没算外围的那些代码,没算 ffmpeg 里其他的大项目。就这一个目录就 20 万行。 不要小看大型项目的规模啊…… |
27
whi147 2023-03-26 08:00:58 +08:00 via iPhone
自己裁剪,我裁剪后就两三兆
|
28
paranoiagu 2023-03-26 08:40:04 +08:00 via Android
应该是静态编译才这么大吧。
|
29
secondwtq 2023-03-26 09:29:40 +08:00 29
这是个有趣的问题。实际上如果只是想把一个东西做得体积很大很简单,一个真实的故事:
一个算法有 2 个较为固定的参数,每个参数有 5 种可能性,那么如果我把这些参数静态编译进去就是 25 种可能性,如果再考虑到在 5 种不同硬件上的组合,那就是 125 种。如果假设每种的代码有 1KB 大,再有三四十个类似的算法,光这玩意就能整出 4MB 来。 类似地,如果工程中涉及到根据外部数据文件生成可执行代码,如 RPC 协议通信等,随着数据越来越多,附加的代码也会越来越多。 另外,编译器优化也可能导致代码体积的指数增长,常见地例如: * 如果一个函数里面出现了对其他函数的多次独立调用,而这些函数又被 inline 。该函数实际生成的代码会包含子函数代码的多个拷贝。如果多个函数 inline 了同一个函数,该子函数代码会被在不同函数中多次拷贝。 * 如果一个函数被多次调用,并且调用时使用了常量参数,该函数的代码可能会被拷贝多份,并将常量参数代入其中单独优化。 * 循环的 unroll 会将循环体代码拷贝多份(虽然一般会有一定的长度限制)。 * 循环的向量化会将循环体代码拷贝多份(不同于 unroll ,这个是向量化逻辑所必须的,因此一般不会限制)。 我这有个对比的例子是 GTK3 。目前我这的 GTK3 包一共 49MB ,不过里面有一堆 GTK 元数据和 locale 之类的东西。只看最关键的 libgtk-3.so ,这玩意一共 7.8 MB ,其中 .text 大概有 3.7MB ,由 500 多个 .o 链接而成,这些 .o 的 .text 大小相加和 libgtk-3.so 的 .text 差不多。.text 最大的前 10% 的 .o ,.text 大小加起来大概 1.6MB 。这些 .o 对应的源码大小加起来大概 7.6MB 。总的源码大小是 17MB (只算 .c ,不算 header )。把 .o 的 .text 大小,和对应 .c 文件的大小画个图,可以很清楚地发现 .c 文件的大小大概是 .text 大小的 4-6 倍,平均值是 5 倍左右。 ffmpeg 包一共 37MB ,其中最大的是 libavcodec.so ,15MB 。.text 有 10MB 。大概有 1100 个 .o (我去除了一部分直接汇编出的 .o ,这些 .o 的 .text 加起来大概 1MB )。.text 最大的前 10% 的 .o ,.text 大小加起来大概 5.3MB 。这些 .o 对应的源码大小加起来大概 5.6MB ,总的源码大小是 19MB 。部分 .o 依然满足 4-6 倍的规律,但是整体的分布分散了许多。很多头部的 .o ,其 .c 文件大小是 .text 文件大小的两倍,一倍,甚至零点几倍。总的来说相比 GTK3 ,ffmpeg 编译生成的 .text 要更大。 进一步研究源码发现: * libavcodec 源码中有很多以 _template.c 结尾的文件,加起来 1MB 左右,这些文件并不会直接编译出 .o (因此并不会计算在上面的 .c 大小上),而主要是被以不同的参数(如位深度)等多次 include 到不同的 .c 中,其实类似于模拟 C++ 的 non-type template parameter 。这些文件中的代码自然也会被拷贝多份。 * 部分源码大量使用了定义宏再多次以不同参数使用宏的技巧,这个还是类似于 non-type template parameter ,同样会导致同样的代码被拷贝多份。 * .o 中的代码存在大量 inline 的痕迹。也出现了一些 constprop 函数。源码中大量函数标记了 always_inline 。 #14 的链接中指出使用 --enable-small 选项(即指示编译器优先优化代码体积)可以数倍降低 libavcodec.so 的大小。暗示编译器优化是巨大体积的重要因素。不过我实测的效果并没有那么吼,.text 大概降低了 40% 左右。相对地,libgtk-3.so 降低了不到 20%。不过确实可以看到很多的 .o 文件 .text 大小成倍地缩小。GTK3 则鲜有缩小超过 30% 的 .o 。 |
30
liberize 2023-03-26 09:33:10 +08:00
chrome 一个 dll 已经超过 200MB 了
|
31
sl0000 2023-03-26 10:26:52 +08:00
一个模板函数就能编译出几十个 G 的执行文件, 和代码行数有关系吗?
|
32
Kisesy 2023-03-26 13:38:53 +08:00
可能是因为高度优化,导致内联过多,或者循环展开等原因吧
|
33
bruce0 2023-03-26 14:28:13 +08:00
pika,一个基于 rocksdb 开发的类似 Redis 的数据库, 以前用手写 MakeFile 组织代码编译,最近开始使用 cmake 重新组织代码编译. 除了几个系统库全部使用静态链接. 在下不才,cmake 默认编译方式那部分是我写的
如果使用 `DCMAKE_BUILD_TYPE=Debug`,这样编译出来的是带调试符号的,最终的可执行文件是 230M, 如果使用 `DCMAKE_BUILD_TYPE=Release` pika 部分代码使用 -O2 优化,依赖库都使用 release 编译, 去掉调试信息 最终的可执行文件是 25M 最后说一下我的结论啊, 编译时加不加调试信息,对最后的二进制体积影响非常大; 有时候可能就是一堆逻辑,没有任何 gui,图片等等资源,编译出来就是几十 M 了, |
34
sharpy 2023-03-26 14:40:57 +08:00
一般自己裁剪吧,disable-everything ,然后看着需求开
|
35
fy 2023-03-26 15:35:52 +08:00
+1 同样疑问,不知道 github 上有没有公开的带 action 的裁剪编译,只需要少数几个编码转换到 silk
|
36
SekiBetu 2023-03-26 18:07:35 +08:00
代码体积就有好几个 G 了,编译算是削减了体积
|
37
herozzm 2023-03-26 18:09:20 +08:00
能到这么小很不容易了,它能转码几乎所有视频编码的视频
|
38
009694 2023-03-26 20:07:51 +08:00 via iPhone
楼主只是疑问为什么 ffmpeg 编译出来体积怎么这么大。 为啥这么多人回复这么充满攻击性和蔑视? 甚至还有 “嫌大你自己写” 这种毫无帮助甚至涉嫌引战的回复
|
39
ch2 2023-03-26 22:33:09 +08:00
因为去掉简单,但是你永远不知道哪个人因为你去掉了什么他的代码就运行不起来,所以就维持在一个兼容性较好的子集里
|
41
standchan 2023-03-27 10:56:09 +08:00
|
42
cyningxu 2023-03-27 11:23:41 +08:00
多复杂的算法编译出来都不会有几十 MB ?这句话一看就不是正常程序员能说出来的
|
43
fresco 2023-03-27 11:43:09 +08:00
我觉得你要用心研究一下就知道它为啥这么“大”了
|
44
noreplay 2023-03-27 12:19:12 +08:00 via Android
晋惠帝只是疑问 何不食肉糜。为啥这么多人对他充满了鄙视和厌恶?甚至还时不时拖来鞭尸?
|
45
mayli 2023-03-27 14:07:37 +08:00 via Android
核心是静态链接一堆库加上自己的库。
类似的有 Linux kernel, 你把所有的驱动都放进去 也能编译出巨大的文件 |
46
mayli 2023-03-27 14:11:25 +08:00
例如,ffmpeg 本体只有
Size 266.55 kB Installed size 688 kB 但是库就多了 比如 ffmpeg-libavcodec: Size 6.48 MB Installed size 14.49 MB x265-libs: Size 3.16 MB Installed size 18.61 MB 想要支持各种格式,同时又兼容小白用静态链接 all in one ,只好这么大了。 https://pkgs.alpinelinux.org/package/edge/community/x86_64/ffmpeg |
47
ko1haha 109 天前
size bench 是个好东西~
|