c – 将lambda函数转换为另一个编译单元中的普通函数会缩短编译时间吗?

我正在研究一个受到不断增长的main()函数困扰的C服务器项目,并且代码库已经发展到编译时间大约为6分钟的时间点(在调试模式下),即使我稍微改变了一下主功能. (main()函数大约5000行!)

我正在使用Visual Studio 2017,并且(据我所知)编译器具有一些预编译的头功能,以及不重新编译未修改函数的功能.但是这些东西目前用处不大,因为大部分逻辑都在main()函数中.

这是我的代码的(非常简化的)版本:

struct GrandServer{
    std::map<std::string,std::function<void(std::string)>> request;
    /* some other functions of this server */
};

int main()
{
    SQLClient sql_client;
    auto query_database=[&sql_client](auto&& callback){/*stuff*/};
    GrandServer server;
    server.request["/my_page.html"] = [](std::string&& data){
        // Do stuff
    };
    server.request["/my_page_2.html"] = [](std::string&& data){
        // Do more stuff
    };
    server.request["/my_page_3.html"] = [](std::string&& data){
        // Do even more stuff
    };
    server.request["/my_page_4.html"] = [&query_database](std::string&& data){
        // Do many many callbacks
        query_database([](std::vector<std::string>&& results){
            std::string id = std::move(results.front());
            do_something_else([id = std::move(id)](auto&& param) mutable {
                /* do more stuff, call more functions that will call back, then answer the client */
            });
        });
    };
    /* Many many more lambda functions */
}

本质上,整个应用程序的核心逻辑包含在main()函数中,通过定义存储在std :: map中的lambdas. lambda函数包含几个级别的lambda函数,主要是从数据库定义(异步)回调.其他独立函数主要包括GrandServer中的函数以及各种实用程序函数(例如时间转换,异步回调实用程序,unicode实用程序等),但它们都不构成应用程序的核心逻辑.这感觉就像非常糟糕的代码蔓延:(

我正在考虑将所有顶级lambda(即直接存储在server.request中的那些)转换为普通的独立成员函数到几个单独的编译单元中,如下所示:

// split definitions of methods in this class over several compilation units
// header file left out for brevity
struct MyServer{
    SQLClient sql_client;
    void query_database=[this](auto&& callback){/*stuff*/};

    void do_my_page(std::string&& data){
        // Do stuff
    }

    void do_my_page_2(std::string&& data){
        // Do stuff
    }

    void do_my_page_3(std::string&& data){
        // Do stuff
    }

    void do_my_page_4(std::string&& data){
        // Do many many callbacks
        query_database([](std::vector<int>&& results){
            do_something_else([](auto&& param){
                /* do more stuff, call more functions that will call back, then answer the client */
            });
        });
    }
};

// main.cpp
struct GrandServer{
    std::map<std::string,std::function<void(std::string)>> request;
    /* some other functions of this server */
};

int main()
{
    GrandServer server;
    MyServer my_server;
    server.request["/my_page.html"] = [&my_server](auto&&... params){my_server.do_my_page(std::forward<decltype(params)>(params)...);};
    server.request["/my_page_2.html"] = [&my_server](auto&&... params){my_server.do_my_page_2(std::forward<decltype(params)>(params)...);};
    server.request["/my_page_3.html"] = [&my_server](auto&&... params){my_server.do_my_page_3(std::forward<decltype(params)>(params)...);};
    server.request["/my_page_4.html"] = [&my_server](auto&&... params){my_server.do_my_page_4(std::forward<decltype(params)>(params)...);};
    /* Lots more lambda functions */
}

虽然这会将main()的大小减小到更容易忍受的程度,但我是否应该期望这会显着减少编译时间?模板实例化的数量不会减少(实际上,我在main()中引入了一些应该内联的新模板lambda转发器).

另请注意,由于回调和使用移动语义捕获变量,将每个逻辑流中的内部lambda函数更改为普通独立成员或非成员函数并不容易. (模板函数和类不能在单独的编译单元中.)但是,每个逻辑流程通常不超过100行,所以我不认为这是必要的.

6分钟编译一个大约6000-7000行的代码库似乎太慢了,我认为这是由于我可怕的长main()函数.如上所述,我是否应该期望破坏此功能以显着改善此项目的编译时间?

最佳答案 你复制了每一个#include<>到stdfafx.h ??这对缩短编译时间大有帮助.编译器可能会抱怨预编译头太大,但默认大小非常小.

-Zm选项控制为预编译头分配的数量,以兆字节为单位.

我看到一些项目的编译速度提高了10多倍.

如果将网络驱动器映射到其中一个本地磁盘,则可以轻松地将编译时间进一步提高3倍.

这是针对该案例的解决方案,它涉及将网络映射替换为注册表中的DOS驱动器.这是我自己设置的内容:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices] 
"R:"="\DosDevices\D:\devel\build"
"S:"="\DosDevices\D:\devel\src"
点赞