timeitrepeat – 通过重复来理解模式

1.问题

在您的软件工程职业生涯中,您可能会遇到一段性能不佳的代码,花费的时间超出了可接受的范围。更糟糕的是,多次执行时性能不一致且变化很大。

此时,您必须接受这样的事实:在软件性能方面,存在很多不确定性。数据可以分布在一个窗口内,有时遵循正态分布。其他时候,它可能会不稳定,没有明显的模式。

2. 方法

这就是基准测试发挥作用的时候。执行代码五次固然很好,但最终,您只有五个数据点,每个数据点都具有太多价值。我们需要对同一代码块进行更多次的重复才能看到模式。

3.问题

一个人应该有多少个数据点?关于它已经有很多文章了,我报道过其中一篇论文

严格的绩效评估需要建立基准,多次执行和测量以处理随机执行时间的变化。研究人员应该提供措施报告结果时的变化。

kalibera, t. 和 jones, r. (2013)。在合理的时间内进行严格的基准测试。 2013年内存管理国际研讨会论文集 https://doi.org/10.1145/2491894.2464160

在测量性能时,我们可能希望测量 cpu、内存或磁盘使用情况,以更全面地了解性能。通常最好从简单的事情开始,比如流逝的时间,因为它更容易形象化。 17% 的 cpu 使用率并不能告诉我们太多信息。应该是什么? 20%还是5%? cpu 使用率并不是人类感知性能的自然方式之一。

4. 实验

我将使用python的timeit.repeat方法来重复一个简单的代码执行块。该代码块只是将 1 到 2000 之间的数字相乘。

from functools import reducereduce((lambda x, y: x * y), range(1, 2000))

这是方法签名

(function) def repeat(    stmt: _stmt = "pass",    setup: _stmt = "pass",    timer: _timer = ...,    repeat: int = 5,    number: int = 1000000,    globals: dict[str, any] | none = none) -> list[float]

什么是重复和数字?

让我们从数字开始。如果代码块太小,它会很快终止,以至于您无法测量任何内容。这个参数提到了 stmt 必须执行的次数。您可以将其视为新的代码块。返回的浮点数是 stmt x 号执行时间。

在我们的例子中,我们将数字保留为 1000,因为乘法到 2000 的成本很高。

接下来,继续重复。这指定了上述块必须执行的重复次数或次数。如果重复次数为 5,则 list[float] 返回 5 个元素。

让我们从创建一个简单的执行块开始

def run_experiment(number_of_repeats, number_of_runs=1000):    execution_time = timeit.repeat(        "from functools import reduce; reduce((lambda x, y: x * y), range(1, 2000))",        repeat=number_of_repeats,        number=number_of_runs    )    return execution_time

我们想以不同的重复值执行它

repeat_values = [5, 20, 100, 500, 3000, 10000]

代码非常简单明了

5. 探索结果

现在我们到达了实验中最重要的部分——解释数据。请注意,不同的人有不同的解释,并且没有单一的正确答案。

您对正确答案的定义很大程度上取决于您想要实现的目标。您是否担心 95% 用户的性能下降?或者,您是否担心尾部 5% 的直言不讳的用户的性能下降?

5.1.多个重复值的执行时间分析统计

正如我们所看到的,最短和最长时间是奇怪的。它展示了一个数据点如何足以改变均值。最糟糕的是,高最小值和高最大值适用于不同的重复值。没有相关性,它只是展示了异常值的力量。

接下来我们转向中位数,并注意到随着重复次数的增加,中位数会下降,除了 20 之外。可以用什么解释呢?它只是表明较少的重复次数意味着我们不一定能全面了解可能的值。

转向截断平均值,其中最低的 2.5% 和最高的 2.5% 被修剪掉。当您不关心异常用户并希望关注中间 95% 用户的表现时,这非常有用。

请注意,尝试提高中间 95% 用户的性能可能会降低异常 5% 用户的性能。

timeitrepeat - 通过重复来理解模式

5.2.多个重复值的执行时间分布

接下来我们想看看所有数据都在哪里。我们将使用 bin 为 10 的直方图来查看数据落在哪里。重复 5 次后,我们发现它们的间距基本相等。这不是人们通常所期望的,因为采样数据应该遵循正态分布。

在我们的例子中,该值的下侧有界,上侧无界,因为运行任何代码都将花费超过 0 秒的时间,但没有上限时间限制。这意味着我们的分布应该看起来像具有长右尾的正态分布。

随着重复值的增加,我们看到右侧出现了一条尾巴。我预计随着重复次数的增加,将会出现一个直方图条,该条的高度足以使异常值被掩盖。

timeitrepeat - 通过重复来理解模式

5.3.值 1000 和 3000 的执行时间分布

我们看看更大的重复值来了解一下怎么样?我们看到一些不寻常的东西。重复 1000 次后,有很多超过 1.8 的异常值,而且看起来更紧密。右边那个重复次数为 3000 的数据仅达到 1.8,并且大部分数据都聚集在两个峰值周围。

这意味着什么?它可能意味着很多事情,包括有时数据可能被缓存,有时却没有。它可以指出代码的许多其他副作用,这些副作用是您可能从未想到的。对于 1000 次和 3000 次重复的分布,我觉得 3000 次重复的 tm95 是最准确的值。

timeitrepeat - 通过重复来理解模式

6. 附录

6.1.代码

import timeitimport matplotlib.pyplot as pltimport jsonimport osimport statisticsimport numpy as npdef run_experiment(number_of_repeats, number_of_runs=1000):    execution_time = timeit.repeat(        "from functools import reduce; reduce((lambda x, y: x * y), range(1, 2000))",        repeat=number_of_repeats,        number=number_of_runs    )    return execution_timedef save_result(result, repeats):    filename = f'execution_time_results_{repeats}.json'    with open(filename, 'w') as f:        json.dump(result, f)def load_result(repeats):    filename = f'execution_time_results_{repeats}.json'    if os.path.exists(filename):        with open(filename, 'r') as f:            return json.load(f)    return Nonedef truncated_mean(data, percentile=95):    data = np.array(data)    lower_bound = np.percentile(data, (100 - percentile) / 2)    upper_bound = np.percentile(data, 100 - (100 - percentile) / 2)    return np.mean(data[(data >= lower_bound) & (data <= upper_bound)])# List of number_of_repeats to testrepeat_values = [5, 20, 100, 500, 1000, 3000]# Run experiments and collect resultsresults = []for repeats in repeat_values:    result = load_result(repeats)    if result is None:        print(f"Running experiment for {repeats} repeats...")        try:            result = run_experiment(repeats)            save_result(result, repeats)            print(f"Experiment for {repeats} repeats completed and saved.")        except KeyboardInterrupt:            print(f"nExperiment for {repeats} repeats interrupted.")            continue    else:        print(f"Loaded existing results for {repeats} repeats.")    # Print time taken per repetition    avg_time = statistics.mean(result)    print(f"Average time per repetition for {repeats} repeats: {avg_time:.6f} seconds")    results.append(result)trunc_means = [truncated_mean(r) for r in results]medians = [np.median(r) for r in results]mins = [np.min(r) for r in results]maxs = [np.max(r) for r in results]# Create subplotsfig, axs = plt.subplots(2, 2, figsize=(15, 12))fig.suptitle('Execution Time Analysis for Different Number of Repeats', fontsize=16)metrics = [    ('Truncated Mean (95%)', trunc_means),    ('Median', medians),    ('Min', mins),    ('Max', maxs)]for (title, data), ax in zip(metrics, axs.flatten()):    ax.plot(repeat_values, data, marker='o')    ax.set_title(title)    ax.set_xlabel('Number of Repeats')    ax.set_ylabel('Execution Time (seconds)')    ax.set_xscale('log')    ax.grid(True, which="both", ls="-", alpha=0.2)    # Set x-ticks and labels for each data point    ax.set_xticks(repeat_values)    ax.set_xticklabels(repeat_values)    # Rotate x-axis labels for better readability    ax.tick_params(axis='x', rotation=45)plt.tight_layout()# Save the plot to a fileplt.savefig('execution_time_analysis.png', dpi=300, bbox_inches='tight')print("Plot saved as 'execution_time_analysis.png'")# Create histograms for data distribution with 10 binsfig, axs = plt.subplots(2, 3, figsize=(20, 12))fig.suptitle('Data Distribution Histograms for Different Number of Repeats (10 bins)', fontsize=16)for repeat, result, ax in zip(repeat_values, results, axs.flatten()):    ax.hist(result, bins=10, edgecolor='black')    ax.set_title(f'Repeats: {repeat}')    ax.set_xlabel('Execution Time (seconds)')    ax.set_ylabel('Frequency')plt.tight_layout()# Save the histograms to a fileplt.savefig('data_distribution_histograms_10bins.png', dpi=300, bbox_inches='tight')print("Histograms saved as 'data_distribution_histograms_10bins.png'")# Create histograms for 1000 and 3000 repeats with 30 binsfig, axs = plt.subplots(1, 2, figsize=(15, 6))fig.suptitle('Data Distribution Histograms for 1000 and 3000 Repeats (30 bins)', fontsize=16)for repeat, result, ax in zip([1000, 3000], results[-2:], axs):    ax.hist(result, bins=100, edgecolor='black')    ax.set_title(f'Repeats: {repeat}')    ax.set_xlabel('Execution Time (seconds)')    ax.set_ylabel('Frequency')plt.tight_layout()# Save the detailed histograms to a fileplt.savefig('data_distribution_histograms_detailed.png', dpi=300, bbox_inches='tight')print("Detailed histograms saved as 'data_distribution_histograms_detailed.png'")plt.show()

以上就是timeitrepeat – 通过重复来理解模式的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1348860.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月13日 12:23:44
下一篇 2025年12月13日 12:23:59

相关推荐

  • AutoDocument – 开源邮件合并替代方案

    AutoDocument – 开源邮件合并替代方案 您好,这篇文章将介绍 AutoDocument,这是一个免费的开源文档生成 Web 应用程序,可将电子表格、数据库和用户表单连接到 Microsoft Word 和 PDF 等文档中。它基于出色的开源库,例如 python-docx-t…

    好文分享 2025年12月13日
    000
  • 为什么 Python 开发人员失业?服务技巧

    科技世界是动态的,工作保障不再是理所当然的,即使对于像 Python 开发这样的急需技能来说也是如此。虽然 Python 仍然是一种流行的语言,但最近的经济衰退和行业转变引发了人们对 Python 开发人员工作稳定性的担忧。让我们找出这些挑战背后的原因,并探索让您的职业生涯面向未来的策略。 Pyth…

    2025年12月13日
    000
  • Pygame开发游戏实用指南—Pygame简介

    在本文中,我们将学习如何下载和安装游戏开发库 pygame,并且我们将运行一个简单的示例项目来熟悉 pygame。 项目代码下载链接:https://github.com/la-vie-est-belle/pygame_codes 安装 pygame 在 windows 上安装 pygame打开命令…

    2025年12月13日 好文分享
    000
  • 使用 Scrapy 和 Playwright 无限滚动抓取页面

    使用 scrapy 抓取网站时,您很快就会遇到各种需要发挥创意或与要抓取的页面进行交互的场景。其中一种场景是当您需要抓取无限滚动页面时。当您向下滚动页面时,这种类型的网站页面会加载更多内容,就像社交媒体源一样。 抓取这些类型的页面的方法肯定不止一种。我最近解决这个问题的一种方法是继续滚动,直到页面长…

    2025年12月13日
    000
  • 测试自动化

    初始设置 下载PythonPython 是一种编程语言。可以从https://www.python.org/downloads/下载。 1.1 激活虚拟环境在您选择类型的目录中python -m venv venv并激活它venv/Scrpts/Activate.ps1 下载机器人框架在终端中输入 …

    2025年12月13日
    000
  • 我的 HNG 之旅第六阶段:利用 Python 公开 DORA 指标

    介绍 对于第 6 阶段,我们的任务是公开 dora(devops 研究),我最近开始了一个使用 python 公开 dora(devops 研究和评估)指标的项目。这次经历教会了我关于 devops 实践以及与合作的复杂性的宝贵经验。在本文中,我将引导您完成整个过程,解释每个指标的含义,并强调一些需…

    2025年12月13日
    000
  • Udemy 上的最佳 Python 课程

    Udemy 上的最佳 Python 课程 Python 是当今世界上最流行的编程语言之一,学习 Python 可以打开各种职业机会的大门。无论您对 Web 开发、数据科学、人工智能还是自动化感兴趣,掌握 Python 都是必不可少的。 Udemy 提供大量 Python 课程,适合从初学者到高级程序…

    2025年12月13日
    000
  • 了解您的数据:探索性数据分析的要点

    探索性数据分析是一种流行的分析数据集并直观地呈现您的发现的方法。它有助于提供对数据集和结构的最大程度的洞察。这将探索性数据分析视为一种理解数据各个方面的技术。为了更好地理解数据,必须确保数据干净、没有冗余、没有缺失值,甚至没有 null 值。 探索性数据分析的类型 主要分为三种:单变量:这是您在任意…

    2025年12月13日 好文分享
    000
  • 简介:Python 游戏第 1 周

    第 1 周:python 和游戏开发基础知识简介 第 1 课:python 基础知识和 pygame 设置 主题:python 语法和基本编程概念(变量、数据类型、循环、函数)。安装和设置 pygame。游戏循环和基本游戏机制介绍。迷你项目:简单绘图应用程序:创建一个允许用户用鼠标在屏幕上绘图的基本…

    2025年12月13日
    000
  • 估计编码任务:可能会出现什么问题?

    以下是“向现有 dataframe 添加哈希值”的任务如何从花费几天时间到消耗几乎整个冲刺的过程。 2022 年第二季度,我开始开发一个数据管道,该管道从 rest 服务获取市场数据并将其存储在 bigquery 表中。这是管道的高级解释。有趣的部分是如何查询数据,将其转换为 dataframe,然…

    2025年12月13日
    000
  • 推荐课程:Pandas 快速入门

    您是否想深入数据分析世界并熟练掌握最强大的数据操作工具之一 pandas?别再犹豫了! labex 提供的 pandas 快速入门课程对于任何有兴趣掌握使用 python 进行数据分析的人来说是一个很好的起点。 释放熊猫的力量 Pandas 是数据科学领域广泛使用的开源库,提供了一套强大的数据操作、…

    2025年12月13日
    000
  • Python 封装现在很棒:“uv”就是您所需要的

    这篇文章的标题是对 glyph 的 python packaging is good now 的引用。我认为可以肯定地说,在这8年里,我们已经从“好”变成了“伟大”。继续阅读我的推理。 是什么让 python 打包对于初学者来说变得困难? 我认为python打包的两个主要困难是 引导,即如何开始!激…

    2025年12月13日
    000
  • 使用 AWS 学习 Python – 第 1 天

    在我的上一篇文章中,我提到了一个与 python 相关的 aws 研讨会,即在 aws 研讨会上学习 python。 想要创建一系列帖子,展示所有实验室实践和针对初学者的 python 教程。 第 1 步 – 登录您的 aws 控制台并确保您有 cloud9 ide 设置环境时请按照 c…

    2025年12月13日 好文分享
    000
  • Python 中的 Lambda 函数解释清楚!

    在这篇文章中,我们将探索 python 中的 lambda 函数: lambda 函数到底是什么?为什么我们需要 Lambda 函数?何时使用 Lambda 函数?最佳实践示例 lambda 函数到底是什么? 在 Python 中,lambda 函数是一种小型匿名函数,可以接受任意数量的参数,但只能…

    2025年12月13日 好文分享
    000
  • 在软件开发生命周期中释放非技术超能力

    当我们想到成为一名优秀的软件开发人员、数据科学家或 QA 工程师的技能时,我们的思绪通常会立即跳到技术专业知识:编码语言、调试技能、人工智能或最新的技术堆栈。但让我们花点时间来了解一下非技术技能,这些技能对于塑造成功的职业生涯也同样有效。这些经常被忽视的属性可能是在软件开发生命周期 (SDLC) 中…

    2025年12月13日
    000
  • 使用 Python 的 NSE 期权链数据 – 第二部分 |沙阿·斯塔万

    在上一篇文章中,我们讨论了如何使用 python 获取 nifty 和 bank nifty 数据。那篇文章的反响很好,因此根据大众的需求,这里有一个扩展版本。在本文中,我们将学习如何每 30 秒从 nse 网站获取期权链数据。此内容仅用于学习目的。 在 python 中,我们将使用 asyncio…

    2025年12月13日
    000
  • 如何使用 Python 抓取 Google 新闻:分步指南

    网络抓取已成为开发人员的一项基本技能,使他们能够从各种在线资源中提取有价值的数据。最受欢迎的抓取目标之一是 google 新闻,它是世界各地最新新闻文章的丰富存储库。本指南旨在提供详细的分步方法来抓取 google 新闻,重点针对中高级开发人员。我们将涵盖从基础知识到高级技术的所有内容,确保您拥有有…

    2025年12月13日
    000
  • 使用 Python 抓取 Google 财经的终极指南

    网络抓取已成为开发人员的一项基本技能,尤其是在提取有价值的财务数据时。谷歌财经是此类数据的热门来源,但抓取这些数据可能具有挑战性。本指南将引导您完成使用 python 抓取 google finance 的过程,涵盖基本和高级技术。无论您是初学者还是中高级开发人员,本文旨在通过实际示例和解决方案满足…

    2025年12月13日
    000
  • 我的创建事件管理 CLI 应用程序的旅程

    我的创建事件管理 cli 应用程序的旅程 介绍 作为软件开发的初学者,最令人兴奋和艰巨的任务之一就是创建您的第一个重要项目。对我来说,这是事件管理 cli 应用程序。这个项目不仅帮助我巩固了对 python 的理解,还向我介绍了 sqlalchemy orm、click 等 cli 库以及软件开发的…

    2025年12月13日
    000
  • 如何使用 Python 抓取亚马逊产品数据

    介绍 在当今数据驱动的世界中,抓取亚马逊产品数据已成为开发人员的一项关键技能,尤其是那些从事电子商务、市场研究和竞争分析的开发人员。本综合指南旨在为中高级公司开发人员提供有效抓取亚马逊产品数据所需的知识和工具。我们将介绍各种方法、工具和最佳实践,以确保您能够收集所需的数据,同时遵守道德和法律准则。有…

    2025年12月13日
    000

发表回复

登录后才能评论
关注微信