C++ 编译输出大小那些事儿

By | 2017-07-17

不知各位撸 C艹 的时候是否遇见过这种尴尬的情况:

用尽了各种 "优雅" 的姿势实现了很多高级的功能 (尤其是模板), 开心的编译一看, 结果发现输出文件巨大无比

虽然这并不是什么特别严重的问题, 但至少存在以下问题:

  • 安装包大小, 尤其对于移动端来说并不是什么好事
  • 大到一定程度, 还会碰到各种神奇的 too many section file too large 之类的错误, 除了拆分代码外没有很好的解决方式

so, 这次来折腾下编译输出大小的优化问题

模板

作为 C艹 世界的一等公民, 模板带来便利的同时, 也带来了很多大坑, 其中之一便是编译输出大小问题

  • 对于同一个模板, 实例化不同类型时, 会为每个类型生成一份完整的代码

    优化套路: 尽量减少实例化类型, 例如, vector<MyType>vector<MyType *> 就是不一样的类型, 尽量考虑只留其中一种

    又如 MyClass<A, B> 尽量拆分为 MyClass0<A>MyClass1<B>, 否则模板参数排列组合特化容易造成模板实例化个数明显增长

  • 通常来说, 所有模板默认 inline

    优化套路: 模板函数中的内容如果比较多, 即使并不需要复用, 也尽量抽取为 extern function, 避免被 inline, 减少模板函数中的代码量

静态变量

尤其是头文件中申明的静态变量, 被多个 cpp 文件引用时, 可能生成多份静态变量

典型例子:

class MyClass {
public:
    static MyClass &instance(void) {
        static MyClass d;
        return d;
    }
};

优化套路:

// in header file
class MyClass {
public:
    static MyClass &instance(void);
};
// in source file
MyClass &MyClass::instance(void)
{
    static MyClass d;
    return d;
}

此外, 应绝对杜绝在头文件直接申明静态变量:

// in header file
static MyClass myClass;

这种虽然不会编译错误, 但是会在所有引用了该头文件的 cpp 内生成一份静态变量,
所以, 虽然可能只是想做些简单的静态注册, 但还是老实的丢 cpp 文件内吧

函数名长度和函数个数

这个一般来说不是什么大问题, 但是个数多的时候问题就会凸显出来了

通常出现在用宏批量生成一些函数的时候, 不过会用到这种的一般也不是常规设计,
所以也没有什么套路可以使, 见机行事吧

转载请注明来自: http://zsaber.com/blog/p/182

既然都来了, 有啥想法顺便留个言呗? (无奈小广告太多, 需审核, 见谅)

Category: C++

发表评论

您的电子邮箱地址不会被公开。