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

为何使用if __name__ == '__main__'调用main会使运行时长增加38%?

问题:为何使用if __name__ == "__main__"结构会使代码运行时长增加38%?

我在学习装饰器教程时修改了代码,代码如下:

from time import perf_counter

def is_prime(num):
    if num <= 1:
        return False
    for i in range(2, int(num**0.5) + 1):
        if num % i == 0:
            return False
    return True

def count_prime_numbers(upper_bound):
    count = 0
    for num in range(upper_bound):
        if is_prime(num):
            count += 1
    print(f"Number of primes: {count}")
    return count

def benchmark(func):
    def wrapper(*args, **kwargs):
        start_time = perf_counter()
        value = func(*args, **kwargs)
        end_time = perf_counter()
        run_time = end_time - start_time
        print(f"Execution of {func.__name__} took {run_time:0.3f} seconds")
        return value

    return wrapper

def main():
    wrapper = benchmark(count_prime_numbers)
    value = wrapper(100000)

if __name__ == "__main__":
    main()

当使用上述if __name__ == '__main__'结构调用main函数时,代码运行时长为0.132秒;但移除该结构直接执行对应逻辑时,运行时长仅为0.096秒。请问为何使用该结构会导致运行时长增加38%?


解答

这种差异主要由Python解释器的函数调用层级、优化策略以及字节码缓存时机共同导致:

  • 多一层函数调用的栈开销:用main函数包裹逻辑时,相当于多了一层函数调用——解释器需要为main函数创建栈帧、处理局部变量(比如wrapper),执行完成后还要销毁栈帧,这会带来额外的运行开销。而直接在顶层执行代码时,没有这一层额外的函数调用栈操作。
  • 闭包与函数引用的优化差异:benchmark返回的wrapper是嵌套闭包函数。当在main内部创建并调用wrapper时,解释器对闭包函数的调用处理比顶层函数调用更复杂,无法触发某些针对全局函数调用的轻量优化;而顶层执行时,wrapper作为全局变量,解释器可以直接定位函数对象,调用效率更高。
  • 字节码缓存时机不同:顶层代码中的wrapper在模块加载阶段就完成了创建和字节码编译,缓存更充分;而main函数里的wrapper是在运行时动态生成的,首次创建时需要额外的编译时间,拉高了整体运行时长。

如果要缩小这种差异,可以尝试:

  • 多次运行取平均值,消除首次运行的编译缓存差异
  • 将wrapper的创建移到顶层,只在main里调用它,比如:
    wrapper = benchmark(count_prime_numbers)
    def main():
        value = wrapper(100000)
    
    if __name__ == "__main__":
        main()
    
    这种方式既保留if __name__ == "__main__"的结构,又避免了在main内部动态创建闭包的开销。

内容的提问来源于stack exchange,提问作者Joseph Coleridge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 22:43:17