ZetCode

Python os.times 函数

上次修改时间:2025 年 4 月 11 日

本综合指南探讨 Python 的 os.times 函数,该函数提供进程和系统 CPU 时间。我们将介绍时间测量、结果解释以及实际的计时示例。

基本定义

os.times 函数以命名元组的形式返回进程和系统 CPU 时间。它以时钟滴答数测量时间(每滴答的秒数会有所不同)。

返回的元组包含:user、system、children_user、children_system 和 elapsed time。在 Windows 上,只有 user 和 system 时间可用。

os.times 的基本用法

此示例演示了 os.times 的基本用法,以获取进程计时信息。我们将打印所有可用的时间测量值。

basic_times.py
import os

# Get process times
times = os.times()

print(f"User CPU time: {times.user}")
print(f"System CPU time: {times.system}")
print(f"Children user CPU time: {times.children_user}")
print(f"Children system CPU time: {times.children_system}")
print(f"Elapsed real time: {times.elapsed}")

# Get clock ticks per second
print(f"\nClock ticks per second: {os.sysconf('SC_CLK_TCK')}")

此代码检索并显示来自 os.times 的所有可用计时信息。用户时间是在用户模式代码中花费的 CPU 时间。

系统时间是在内核模式中花费的 CPU 时间。子进程时间考虑了派生的进程。经过的时间是自进程启动以来的实际时间。

测量代码执行时间

我们可以使用 os.times 来测量代码块消耗的 CPU 时间。这与测量实际时间的 time.time() 不同。

measure_execution.py
import os
import math

def calculate_primes(n):
    return [x for x in range(2, n) 
            if all(x % y != 0 for y in range(2, int(math.sqrt(x)) + 1))]

# Get initial times
start = os.times()

# Execute CPU-intensive task
primes = calculate_primes(10000)

# Get final times
end = os.times()

# Calculate differences
user_time = end.user - start.user
system_time = end.system - start.system
total_cpu = user_time + system_time

print(f"User CPU time used: {user_time:.2f} seconds")
print(f"System CPU time used: {system_time:.2f} seconds")
print(f"Total CPU time used: {total_cpu:.2f} seconds")
print(f"Found {len(primes)} prime numbers")

这测量了一个素数计算函数消耗的 CPU 时间。用户时间显示在我们代码中的时间,系统时间显示内核操作。

请注意,这测量的是 CPU 时间,而不是实际时间。对于 I/O 密集型操作,实际时间可能更相关(请改用 time.time())。

比较进程和子进程时间

此示例演示了 os.times 如何通过派生子进程来跟踪主进程及其子进程的 CPU 使用率。

children_times.py
import os
import subprocess

print("Before any child processes:")
initial = os.times()
print(f"Children user: {initial.children_user}")
print(f"Children system: {initial.children_system}\n")

# Run several external commands
commands = ["sleep 1", "ls -l /", "df -h"]
for cmd in commands:
    subprocess.run(cmd, shell=True)

print("\nAfter running child processes:")
final = os.times()
print(f"Children user: {final.children_user}")
print(f"Children system: {final.children_system}")

print("\nChild process totals:")
print(f"Total user time: {final.children_user - initial.children_user}")
print(f"Total system time: {final.children_system - initial.children_system}")

该示例运行多个 shell 命令,并显示子进程时间如何累积。sleep 命令使用的 CPU 很少,而 ls 和 df 使用的 CPU 更多。

当您的程序派生许多子进程并且您想要分别跟踪它们的组合资源使用情况时,子进程时间非常有用。

计算 CPU 利用率

我们可以通过比较 CPU 时间与实际时间来计算 CPU 利用率百分比。这显示了 CPU 被使用的效率。

cpu_utilization.py
import os
import time

def busy_work():
    sum = 0
    for i in range(10**7):
        sum += i
    return sum

start_times = os.times()
start_wall = time.time()

# Perform work
result = busy_work()

end_times = os.times()
end_wall = time.time()

# Calculate times
cpu_time = (end_times.user - start_times.user) + \
           (end_times.system - start_times.system)
wall_time = end_wall - start_wall

utilization = (cpu_time / wall_time) * 100

print(f"CPU time used: {cpu_time:.2f} seconds")
print(f"Wall-clock time: {wall_time:.2f} seconds")
print(f"CPU utilization: {utilization:.1f}%")
print(f"Result: {result}")

这通过比较 CPU 时间与实际时间来计算 CPU 利用率。100% 意味着该进程在执行期间持续使用了所有可用的 CPU。

对于多核系统,如果使用多个内核,利用率可能会超过 100%。此示例仅测量单线程性能。

分析函数性能

os.times 可用于通过测量其 CPU 时间消耗来分析各个函数。这有助于识别性能瓶颈。

function_profiling.py
import os

def fast_operation():
    return sum(range(1000))

def slow_operation():
    total = 0
    for i in range(1000000):
        total += i * i
    return total

def profile_function(func):
    start = os.times()
    result = func()
    end = os.times()
    
    cpu_time = (end.user - start.user) + (end.system - start.system)
    print(f"{func.__name__} took {cpu_time:.4f} CPU seconds")
    return result

print("Profiling function performance:")
profile_function(fast_operation)
profile_function(slow_operation)

这创建了一个简单的分析函数,用于测量其他函数使用的 CPU 时间。快速操作很快完成,而慢速操作需要更长的时间。

对于更复杂的分析,请考虑 Python 的内置 profile 或 cProfile 模块,它们提供更详细的分析。

比较 os.times 和 time.time

此示例将 os.times(CPU 时间)与 time.time(实际时间)进行对比,以显示哪种情况适合性能测量。

times_vs_time.py
import os
import time

def cpu_intensive():
    return sum(i*i for i in range(10**6))

def io_intensive():
    with open("temp.txt", "w") as f:
        for i in range(10000):
            f.write(f"Line {i}\n")
    os.remove("temp.txt")

def measure(func):
    print(f"\nMeasuring {func.__name__}:")
    
    # CPU time measurement
    start_cpu = os.times()
    func()
    end_cpu = os.times()
    cpu_time = (end_cpu.user - start_cpu.user) + \
               (end_cpu.system - start_cpu.system)
    
    # Wall-clock time measurement
    start_wall = time.time()
    func()
    end_wall = time.time()
    wall_time = end_wall - start_wall
    
    print(f"CPU time: {cpu_time:.4f} seconds")
    print(f"Wall time: {wall_time:.4f} seconds")
    print(f"Ratio: {cpu_time/wall_time:.1%}")

measure(cpu_intensive)
measure(io_intensive)

CPU 密集型函数显示相似的 CPU 时间和实际时间。I/O 密集型函数显示比实际时间低得多的 CPU 使用率,这是由于等待造成的。

使用 os.times 进行 CPU 密集型优化,使用 time.time 进行包括 I/O 等待在内的整体性能测量。

平台差异

最佳实践

资料来源

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 Python 教程