You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何通过ctypes调用C代码比直接运行C程序更快?

Python调用C函数比GCC编译的C可执行文件更快的原因

问题描述

我做了一项Python与C的性能对比测试:编写程序计数到10亿,通过ctypes让Python调用C函数,同时直接运行C程序。测试结果显示Python调用C函数的耗时(约0.29-0.305秒)反而比直接运行GCC编译的C程序(约0.51-0.55秒)更快,这与预期不符。换用Clang编译后结果恢复正常(C程序更快)。

测试代码

C代码count.c:

// count.c
#include <stdio.h>

long int count(long int n) {
    long int number = 0;
    for(long i = 0; i < n; i++) {
        number++;
    }
    return number;
}

int main() {
    printf("%ld\n", count(1000000000));
    return 0;
}

Python代码count.py:

# count.py
from ctypes import CDLL

so_file = "./count.so"
count_func = CDLL(so_file).count

print(count_func(1000_000_000))

环境信息

  • GCC版本:gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
  • Clang版本:Ubuntu clang version 14.0.0-1ubuntu1
  • 系统:Ubuntu 22.04.1 LTS x86_64

原因分析

1. GCC对可执行文件与共享库的默认优化策略不一致

这是核心原因:

  • 编译可执行文件时:GCC默认使用-O0(无优化)等级,编译器保留完整调试信息,不对循环做任何优化——count函数里的循环会被逐次执行,完全没有常量折叠、循环展开等优化,执行效率极低。
  • 编译共享库时:GCC会自动启用部分优化(比如-O1级别的部分优化项),此时编译器能识别到number的最终值等于输入参数n,直接返回n跳过循环,执行速度大幅提升。

Python调用的是经过优化的共享库,而直接运行的是未优化的C可执行文件,因此出现Python调用更快的反直觉结果。

2. Clang的统一优化行为

Clang在编译可执行文件和共享库时,默认优化策略更统一,都会对这种无意义的循环做常量折叠优化,直接返回n。因此无论是直接运行Clang编译的C程序,还是Python调用其编译的共享库,速度都很快;且C程序因为没有Python调用的额外开销,表现会更优。

3. 验证方式

可以通过手动指定优化等级验证:

  • 用GCC编译可执行文件时加-O2优化:gcc -O2 count.c -o count_opt,此时直接运行该可执行文件的速度会和Python调用共享库相当甚至更快。
  • 用GCC编译共享库时强制-O0:gcc -shared -fPIC -O0 count.c -o count_noopt.so,此时Python调用该共享库的速度会变慢,与未优化的C可执行文件耗时接近。

内容的提问来源于stack exchange,提问作者Gray Hat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 21:35:23