zoukankan      html  css  js  c++  java
  • C++17引入的模块为什么能加快编译速度?


    https://www.zhihu.com/question/37330979/answer/73595024


    作者:hearts zh
    链接:https://www.zhihu.com/question/37330979/answer/71692790
    来源:知乎
    著作权归作者所有,转载请联系作者获得授权。

    首先要说明的是,模块(module)在不同编程语言的并不完全一样,只是名字相同而已。查查英英词典,module: unit, part, component, segment, element。大概就是整体的一小部分的意思。软件里面一般指可以重用的部分。不同语言对于这个东西显然有不同的理解/定义。不细表。

    要回答你的问题,首先要理解为啥c++编译慢呢?这要从C说起。C一开始采用了拷贝-插入模型。#include关键字,就是把另外一个文件原封不动的拷贝到现在的文件。为啥这样设计,我也不敢乱说,但这样设计,带来了一些常用的用法,这些用法在10多年前C++世界,甚至在现在的嵌入式世界,都蛮流行的。比如说,
    //common.h
    #define DEBUG
    
    //main.c
    #include "common.h"
    #include "a.h"
    
    int main() {
      #ifdef DEBUG
      debug_buffer[0] = 1;
      debug_print_buffer();
      #endif
      return 0;
    }
      
    
    //a.h
    #include "common.h"
    #ifdef DEBUG
    extern int debug_buffer[10000000];
    extern void debug_print_buffer();
    #endif
    
    
    //a.c
    #include "a.h"
    #ifdef DEBUG
    int debug_buffer[10000000];
    void debug_print_buffer() {}
    #endif 
    


    代码随便写的凑合着看,大概意思就酱。这种用法,只有拷贝-插入模式才有用。common里面的#define DEBUG影响了a.h,a.c和main.c。

    当然也带来了一系列负面影响,例如如果a.h #include了common.h, b.h也#include了 common.h,如果a.h #include b.h的话呢,common.h就被拷贝插入了2次。不但影响编译速度,而且重复定义了common.h里面的东西。所以呢,对于c和c++来说,所有的.h里,都要写一些奇怪的东西防止被#include 2次。这大家都知道了,就不深入了。

    以上为C。其实没有什么大问题。为什么到C++就变成问题了呢?这要从C/C++编译的另一面说起。从编译角度来讲,C/C++是每个.c, .cpp文件单独编译,最后放到一起链接。例如你有a.c和b.c,其实a.c和b.c是分别编译,最后放到一起连接成可执行文件或者库。

    这其实是完全没问题的,因为分别编译好处是显而易见的,一旦b.c被更新了,a.c不需要重新编译一遍。加快了编译速度。

    那你说有什么问题?问题就在c++中 .h 文件太长了!!特别是.h文件中还有模板!

    对于C,.h文件无非就是函数声明之类的一些东西,但C++ .h文件是类,可以有类的成员定义,是模板,必须有模板的成员定义。

    #include <iostream>根据某些实现,带来上万行的拷贝-插入,里面还全是模板。

    假设a.cpp里有iostream,b.cpp里有iostream,因为分别编译,带来2万行的拷贝-插入。你有10000个.cpp文件就是10000*10000行的拷贝-插入重复编译。当然第一次编译很慢,之后因为你一般不会更新所有.cpp,会快一点,但也相当慢。

    你说,为什么不把iostream编译一次,存起来,存到cache,其他的文件直接用?原因也很简单,不行!

    iostream里面的具体实现,取决于include他的文件的环境。例如iostream里面有一个#ifdef DEBUG,那么#include <iostream>时,是否#define DEBUG取决了iostream里的东西并不一样。根本没法cache。

    ------------------------------------------------------------------

    以上。那么module在C++中是什么?module的设计准则之一,就是module是独立的,不受import module的文件的环境影响。当然,module也不影响别人。于是编译好的module就可以被cache起来,具体编译器可以采用不同实现。可以cache到文件,内存,等等地方。

  • 相关阅读:
    [kuangbin带你飞]专题七 线段树
    [kuangbin带你飞]专题六 最小生成树
    [kuangbin带你飞]专题五 并查集
    [kuangbin带你飞]专题四 最短路练习
    [kuangbin带你飞]专题三 Dancing Links
    [kuangbin带你飞]专题二 搜索进阶
    [kuangbin带你飞]专题一 简单搜索
    常用算法模板
    ACM程序设计选修课——Problem E:(ds:图)公路村村通(Prim)
    HDU——5667Sequence(矩阵快速幂+费马小定理应用)
  • 原文地址:https://www.cnblogs.com/ztguang/p/12645046.html
Copyright © 2011-2022 走看看