我用现代 C++ 写了个 Web 框架,这 25 个设计细节让性能拉满
写在前面 两万多行代码写下来,我把踩过的坑和想明白的事都总结在这了。不讲概念,只聊实战中每个设计"为什么这么做"。 搞 C++ Web 框架这事,从第一行代码到现在,说实话走了不少弯路。今天不聊怎么用,聊聊底层那些设计决策——为什么要这么写,当时碰到了什么问题,怎么一步步改成现在这样的。 一、编译期就把活干完 1. 一套模板搞定 TCP 和 SSL 最早我是分别写了 TcpConnection 和 SslConnection 两个类,代码重复率 80%以上,改一个 bug 要改两遍。后来换成 GenericConnection<SocketType>,内部用 if constexpr 做分支: 1 2 3 if constexpr (hIsSslStream<SocketType>) { co_await stream_.async_handshake(...); } 编译器直接在编译期把不匹配的分支丢掉——纯 TCP 的二进制里一个字节的 SSL 代码都没有。维护成本砍半,运行时零开销。这不是什么高深技巧,但真正落地用好的项目不多。 2. 用不到的模块,连编译都不参与 数据库、OpenAPI 这些模块,不是每个项目都用得上。我用 CMake option + 宏隔离的方式处理: 1 option(HICAL_WITH_DATABASE "Enable DB middleware" OFF) 代码里所有 DB 相关的逻辑都包在 #ifdef HICAL_HAS_DATABASE 里。你不开这个 option,这些代码连语法检查都不走,更别说占二进制体积了。比运行时搞个 feature flag 干净太多——运行时 flag 意味着代码虽然不执行,但死代码还在那占着 icache。 3. TRACE 日志:Release 下彻底消失 开发时满屏 TRACE 日志方便调试,但生产环境绝对不能有这些开销。我的做法是 NDEBUG 下 HICAL_LOG_TRACE 直接展开成 ((void)0)——注意,这不是"判断级别后跳过",而是连参数求值的代码都不存在于二进制中。 ...