首页 > 编程问答 >time.perf_counter() 或 time.perf_counter_ns() 给出奇怪且不正确的值

time.perf_counter() 或 time.perf_counter_ns() 给出奇怪且不正确的值

时间:2024-07-27 16:43:01浏览次数:10  
标签:python time multiprocessing performancecounter timeit

我在处理多处理时编写了这个简单的代码。

from multiprocessing import Process, cpu_count
import time

def counter(num):
    count = 0
    while count < num:
        count += 1

def main():
    print(cpu_count())

  
    a = Process(target=counter, args=(250000000,))
    b = Process(target=counter, args=(250000000,))
    c = Process(target=counter, args=(250000000,))
    d = Process(target=counter, args=(250000000,))
    
    a.start()
    b.start()
    c.start()
    d.start()

    a.join()
    b.join()
    c.join()
    d.join()

    
    print("Finished in:", time.perf_counter(), "seconds")

if __name__ == "__main__":
    main()

嗯,我的代码中的所有内容都运行得很完美,除了 time.perf_counter() 为一个几乎只花了 2-3 秒的程序提供了 7000 秒的时间。我尝试使用 time.perf_counter_ns() 但它没有达到我的预期。首先,它给了我科学形式的值,当我将纳秒转换为秒时,它仍然给了我与之前相同的结果。而不是那些,我尝试使用 timeit 模块打印 timeit.timeit() ,它确实给了我像 0.0143249234 这样的值,用于一个花费超过 2 秒的程序。当我打印 cpu_cores 而不是显示我的电脑有多少个核心时,它确实给了我这个 <bound method BaseContext.cpu_count of <multiprocessing.context.DefaultContext object at 0x000001B68DDCD1C0>>


代码中出现奇怪的时间测量结果是因为你误解了 cpu_count() 的使用方式以及 time.perf_counter() 的行为。让我们来分解一下:

问题 1: cpu_count() 的误用

  • 你正在将 cpu_count() 作为一个可调用对象打印出来,而不是调用它。这就是为什么你会看到 <bound method...> 的输出。为了获得 CPU 核心数量,你应该调用该函数:

python print(cpu_count()) # 正确调用函数

问题 2: time.perf_counter() 的范围

  • time.perf_counter() 测量的是自某个未定义的时间点以来经过的总时间,包括你的 Python 进程休眠的时间。当你启动一个进程时, time.perf_counter() 已经开始计时,它会持续计时,即使你的进程没有在执行任何操作。

  • 在你的代码中,你正在你的 main() 函数中启动 time.perf_counter() ,然后启动你的进程。当你的进程在后台运行时, main() 函数会立即完成,而 time.perf_counter() 则会继续计时。这意味着 time.perf_counter() 捕获的时间不仅包括你的进程的执行时间,还包括 main() 函数完成到你的进程完成之间的时间。

解决方案

为了准确测量你的多进程代码的执行时间,你需要在启动你的进程之前和之后立即调用 time.perf_counter()

import multiprocessing
import time

def counter(num):
    count = 0
    while count < num:
        count += 1

def main():
    num_cores = multiprocessing.cpu_count()
    print("CPU 核心数量:", num_cores)

    start_time = time.perf_counter()  # 在启动进程之前开始计时

    a = multiprocessing.Process(target=counter, args=(250000000,))
    b = multiprocessing.Process(target=counter, args=(250000000,))
    c = multiprocessing.Process(target=counter, args=(250000000,))
    d = multiprocessing.Process(target=counter, args=(250000000,))

    a.start()
    b.start()
    c.start()
    d.start()

    a.join()
    b.join()
    c.join()
    d.join()

    end_time = time.perf_counter()  # 在进程完成后停止计时

    print("完成时间:", end_time - start_time, "秒")

if __name__ == "__main__":
    main()

通过这种方式,你将只测量你的进程实际运行所花费的时间。

标签:python,time,multiprocessing,performancecounter,timeit
From: 78798476

相关文章

  • python_wholeweek2
    目录编码方式open函数的使用open进行写入时有关于编码解码前面的open函数使用加了一个r绝对路径和相对路径的使用open函数的几种modewithopen的使用(对比open函数而言补充知识点,之前用过replace但是给忘了附加对于python识别文本时的编码错误链接解释编码方式​ txt文件的编码方......
  • Python 与 Visual Studio Professional 2022(64 位)- 预览版本 5.0 交互窗口挂起
    我正在MicrosoftVisualStudioProfessional2022(64位)-预览版17.11.0预览版5.0上运行Python开发工作负载。我正在关注VisualStudio中的Python教程https://learn.microsoft.com/en-us/visualstudio/python/tutorial-working-with-python-in-visual-studio-st......
  • Python面试宝典第19题:最小路径和
    题目        给定一个包含非负整数的mxn网格grid,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。        示例1:输入:grid=[[1,3,1],[1,5,1],[4,2,1]]输出:7解释:因为路径1→3→1→1→1的总......
  • 基于python的出租车管理网站的设计与实现【源码+文档+PPT】
    ......
  • 如何在Linux上的python中以后台模式打开程序?
    我需要在Linux上以后台模式使用python打开另一个程序。我尝试过subprocess.call("yourcommand")但它不是后台模式。并且os.startfile("file")在Linux上不起作用。请帮助我。可以使用Python的subprocess模块在Linux上以后台模......
  • 【学习笔记】Matlab和python双语言的学习(TOPSIS法)
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、TOPSIS法1.模型原理2.基本步骤(1)原始矩阵正向化(2)正向矩阵标准化(3)计算得分并归一化二、代码实现----Matlab1.主程序2.正向化处理函数3.极小型正向化函数4.中间型正向化函数5.区间型正向化......
  • 基于Python flask 的豆瓣电影top250数据评分可视化
    跟着CSDN上学习一下爬虫和简单的可视化分析,最后完成了一个简单的小项目。1.项目简介        基于Pythonflask的豆瓣电影评分可视化。通过采用Python编程语言,使用flask框架搭建影视系统,并使用相关技术实现对豆瓣网站的爬取、数据存储和可视化分析。2、成果展示:......
  • 获取 Python Decimal 的精确十进制字符串表示形式?
    如果我有一个PythonDecimal,我怎样才能可靠地获得数字的精确十进制字符串(即不是科学记数法)表示而不带尾随零?例如,如果我有:>>>d=Decimal('1e-14')我会像:>>>get_decimal_string(d)'0.00000000000001'但是:Decimal类没有任何to_......
  • python datetime timedelta 对于没有小数部分的时间返回 0.0
    我正在使用datetime.timedelta来获取python中进程的持续时间。defget_time_difference(start_time,end_time):time_in_seconds=(end_time-start_time)returnstr(datetime.timedelta(seconds=time_in_seconds))[:-3]文档指出“所有参数都是可选的......
  • 如何运行从我正在编写的另一个 Python 脚本获取命令行参数的 Python 脚本?
    我有一个python3脚本,如下所示:...defmain():parser=argparse.ArgumentParser(description='Performnormalisationchecksonpass2files')parser.add_argument('-p','--parser',action='store',help='parse......