实测:一次 sendEvent 派发 49–55ns,postEvent 入队加排空 290ns(5.9 倍);忙等 200ms 错过 20 个 10ms tick、事后只补发 1 个事件(错过的 tick 不补帧);VeryCoarseTimer 把 300ms 变成 1000.9ms(3.3 倍),CoarseTimer 的 50ms 实测 62.6ms(+25%);Windows 的 15.6ms tick 困不住 Qt——Sleep(1) 实测 14.9ms,而 QTimer(1ms) 是 1.05ms,因为有活动定时器时进程分辨率被抬到 1ms(tick 里 Sleep(1)=1.63ms);槽里调 processEvents() 每层重入吃 13.3KB 栈,60 层就是 786KB;1000 次 update() 只换来 1 次 Paint,500 次 resize() 却产生 499 个 Resize 事件。
实测:Q_OBJECT 让 108 行头文件膨胀成 1109 行 C++、单 TU 编译 +26%,但对象体积一字节不加;忘跑 moc 的签名是 `undefined reference to 'vtable for Widget'`;CMAKE_PREFIX_PATH 不写,CMake 会静默挑中另一套 Qt 再在链接期炸出 3 条 __imp_ 未定义引用;w.show() 返回 0.0ms 且一次 Paint 都没派发。
实测:不带类型码前缀的裸字符串 connect 恒失败并报 `Use the SIGNAL macro to bind ...`;宏式 connect 比函数指针版贵 2.7 倍、字符串版贵 4.0 倍、拼错名字再贵 4.6 倍;emit 每多一个连接 +15–22ns,跨线程入队是同线程的 15–21 倍;`QMetaObject::Connection` 在 6.9 已无 `isValid()`;`connectSlotsByName` 重复调用会把同一个槽接两遍;`property()` 比直接 getter 慢 120 倍且代价随属性在表里的**位置**线性上涨。
实测:同样 120 个矩形,画在窗口 DC 上每个 16.9 微秒,画在内存 DC 上每个 1.3 微秒(13 倍),双缓冲把一帧从 2.110 毫秒压到 0.293 毫秒;SetPixel 每点 581 纳秒而直接写位图内存 1.5 纳秒(398 倍);StretchBlt 缩小 8 倍时 HALFTONE 比 COLORONCOLOR 慢 207 倍;一次提前的 ReleaseDC 让后面所有 GetDeviceCaps 静默返回 0,而 GetLastError 一动不动。
实测:句柄值是 4 字节步进的表索引,关掉再建立刻复用;一个线程的消息队列只能堆 10000 条(第 10001 次 PostMessage 报 1816 配额不足);同线程 SendMessage 56 纳秒,跨线程 27.8 微秒,差 493 倍;USER 与 GDI 各自的配额都是每进程 10000,而 GDI 耗尽时 GetLastError 一动不动。
实测:windres 编一个 2.4KB 的 .rc 要 482–905 毫秒,编一个装着 4.3MB 载荷的 .rc 也是 588–905 毫秒——成本全在启动预处理器;.rc 里的 UTF-8 中文被按 ACP=936 读进去,字符串从 6 个字符变成 9 个乱码码点,而 A 版 LoadString 又把它"错进错出"还原成正确的中文;图标请求 128×128 时系统宁可用 256 缩小也不用 48 放大;对每个资源名再查一次语言,shell32 的全量枚举从 6.02 毫秒变成 18,994 毫秒。
在公众号、小红书、各种信息流之外,一个自己拥有域名的静态站点仍然值得拥有。
用 glob loader 加 zod schema 把 Markdown 变成有类型约束的数据源,写错字段构建期就报错。