尝试/捕获或验证速度?

2023-12-29

我正在使用 Python,每当我必须验证函数输入时,我都会假设输入有效,然后捕获错误。

就我而言,我有一个通用的Vector()我用它来做一些不同的事情,其中​​之一就是加法。它的功能既是Color()类并作为Vector(),所以当我向Color(),它应该将该常数添加到每个单独的组件中。Vector() and Vector()添加需要按组件添加。

该代码用于光线追踪器,因此任何速度提升都很棒。

这是我的简化版本Vector() class:

class Vector:
  def __init__(self, x, y, z):
    self.x = x
    self.y = y
    self.z = z

  def __add__(self, other):
    try:
      return Vector(self.x + other.x, self.y + other.y, self.z + other.z)
    except AttributeError:
      return Vector(self.x + other, self.y + other, self.z + other)

我目前正在使用try...except方法。有人知道更快的方法吗?


EDIT:感谢这些答案,我尝试并测试了以下解决方案,该解决方案在添加之前专门检查类名Vector()对象:

class Vector:
  def __init__(self, x, y, z):
    self.x = x
    self.y = y
    self.z = z

  def __add__(self, other):
    if type(self) == type(other):
      return Vector(self.x + other.x, self.y + other.y, self.z + other.z)
    else:
      return Vector(self.x + other, self.y + other, self.z + other)

我使用这两个代码块进行了速度测试timeit http://docs.python.org/library/timeit.html,结果非常显着:

 1.0528049469 usec/pass for Try...Except
 0.732456922531 usec/pass for If...Else
 Ratio (first / second): 1.43736090753

我还没有测试过Vector()与 一起上课no无论如何输入验证(即将检查移出类并移至实际代码中),但我想它甚至比if...else method.


更新较晚: 回头看这段代码,这是not一个最优解。

OOP 使这变得更快:

class Vector:
  def __init__(self, x, y, z):
    self.x = x
    self.y = y
    self.z = z

  def __add__(self, other):
    return Vector(self.x + other.x, self.y + other.y, self.z + other.z)

class Color(Vector):
  def __add__(self, other):
    if type(self) == type(other):
      return Color(self.x + other.x, self.y + other.y, self.z + other.z)
    else:
      return Color(self.x + other, self.y + other, self.z + other)

我赞成马特·乔伊纳的回答,但想包括一些额外的观察结果,以明确指出,除了其他几个因素之外,还有4在预检查条件(称为 LBYL 或“三思而后行”)和仅处理异常(称为 EAFP 或“更容易请求宽恕而不是许可”)之间进行选择时,这一点很重要。

这些时间是:

  • 检查时间succeeds与LBYL
  • 检查时间fails与LBYL
  • 发生异常时的时机is not用 EAFP 抛出
  • 发生异常时的时机is用 EAFP 抛出

附加因素是:

  • 检查成功/失败或抛出/未抛出异常情况的典型比率
  • 是否存在阻止使用 LBYL 的竞争条件

最后一点是需要首先解决的问题:如果存在竞争条件的可能性,那么你别无选择,你must使用异常处理。一个经典的例子是:

if <dir does not exist>:
    <create dir> # May still fail if another process creates the target dir

由于 LBYL 不排除此类情况的例外情况,因此它没有提供任何实际好处,也无需做出判断:EAFP 是唯一能够正确处理竞争条件的方法。

但如果不存在竞争条件,这两种方法都可能可行。他们提供不同的权衡:

  • 如果没有引发异常,则 EAFP 接近免费
  • 然而,如果发生异常,其成本相对较高,因为在展开堆栈、创建异常并将其与异常处理子句进行比较方面涉及相当多的处理
  • 相比之下,LBYL 会产生潜在的高固定成本:无论成功还是失败,总是会执行额外的检查

然后得出以下决策标准:

  • 这段代码对于应用程序的速度至关重要吗?如果不是,那么不要担心两者中哪一个更快,而担心两者中哪一个更容易阅读。
  • 预检查是否比引发和捕获异常的成本更昂贵?如果是,那么 EAFP 总是更快,应该使用。
  • 如果答案是否定的,事情会变得更有趣。在这种情况下,哪个更快将取决于成功或错误情况是否更常见,以及预检查和异常处理的相对速度。明确回答这个问题需要真正的时序测量。

作为一个粗略的经验法则:

  • 如果存在潜在的竞争条件,请使用 EAFP
  • 如果速度并不重要,只需使用您认为更容易阅读的内容
  • 如果预检查费用昂贵,请使用 EAFP
  • 如果您希望操作在大多数情况下都能成功*,请使用 EAFP
  • 如果您预计操作失败超过一半的时间,请使用 LBYL
  • 如有疑问,请测量

*在这种情况下,人们对“大多数时候”的看法会有所不同。对我来说,如果我期望操作成功一半以上,我就会理所当然地使用 EAFP,直到我有理由怀疑这段代码是实际的性能瓶颈。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试/捕获或验证速度? 的相关文章

  • 删除 tkinter 文本默认绑定

    我正在制作一个简单的 tkinter 文本编辑器 但我想要所有默认绑定文本小部件如果可能的话删除 例如当我按Ctrl i它默认插入一个制表符 我制作了一个事件绑定来打印文本框中有多少行 我将事件绑定设置为Ctrl i以及 当我运行它时 它会
  • 在 python 中发送标头[重复]

    这个问题在这里已经有答案了 我有以下 python 脚本 我想发送 假 标头信息 以便我的应用程序就像 Firefox 一样运行 我怎么能这么做呢 import urllib urllib2 cookielib username passw
  • Discord.py 斜线命令在 cogs 中不起作用

    我正在构建一个不和谐的机器人 并且想要在 cogs 内使用斜杠命令 但这些命令不显示或工作 这是代码 cog guild ids 858573429787066368 861507832934563851 class Slash comma
  • DataFrame.loc 的“索引器太多”

    我读了关于切片器的文档 http pandas pydata org pandas docs stable advanced html using slicers一百万次 但我从来没有理解过它 所以我仍在试图弄清楚如何使用loc切片Data
  • Python 中“is”运算符的语义是什么?

    如何is运算符确定两个对象是否相同 它是如何工作的 我找不到它的记录 来自文档 http docs python org reference datamodel html 每个对象都有一个身份 一个类型 和一个值 对象的身份 一旦发生就永远
  • 如何在Python中手动对数字列表进行排序?

    规格 Ubuntu 13 04 Python 3 3 1 背景 Python的初学者 遇到了这个 手动排序 问题 我被要求做的事情 让用户输入 3 个数值并将它们存储在 3 个不同的变量中 不使用列表或排序算法 手动将这 3 个数字从小到大
  • 右键单击 QPushButton 上的 contextMenu

    对于我的应用程序 我在 Qt Designer 中创建了一个 GUI 并将其转换为 python 2 6 代码 关于一些QPushButton 与设计器创建 我想添加右键单击上下文菜单 菜单选项取决于应用程序状态 如何实现这样的上下文菜单
  • 实体框架中的重复键异常?

    我试图捕获当我将具有给定用户名的现有用户插入数据库时 引发的异常 正如标题所说 我正在使用 EF 当我尝试将用户插入数据库时 引发的唯一异常是 UpdateException 如何提取此异常以识别其是否是重复异常或其他异常 catch Up
  • Pygame:有人可以帮我实现双跳吗?

    我知道已经有其他关于此问题的帖子了 但我的运动系统与我发现的有点不同 所以随后我问这个问题 我的运动系统基于一个名为的命名元组Move up left right down 然后就是这个 def update self move block
  • Kivy TextInput 水平和垂直对齐(文本居中)

    如何在 Kivy 的 TextInput 中水平居中文本 I have the following screen But I want to centralize my text like this 这是我的 kv 语言的一部分 BoxLa
  • 未定义异常变量时通过引用捕获

    捕获异常时 标准指导是按值抛出 按引用捕获 据我了解 这有两个原因 如果由于内存不足异常而引发异常 我们将不会调用可能终止程序的复制构造函数 如果异常是继承层次结构的一部分 我们可能会对异常进行对象切片 如果我们有一个场景 我们没有在 ca
  • 列表中的特定范围(python)

    我有一个从文本字符串中提取的整数列表 因此当我打印该列表 我称之为test I get 135 2256 1984 3985 1991 1023 1999 我想打印或制作一个仅包含特定范围内的数字的新列表 例如1000 2000之间 我尝试
  • 在字符串内打印单引号

    我想输出 XYZ s ABC 我在Python IDLE中尝试了以下3条语句 第一条和第二条语句输出 a before 带打印功能的第三条语句不输出 before 作为 Python 新手 我想了解为什么 之前输出 在第 1 条和第 2 条
  • 在 4K 屏幕上使用 Matplotlib 和 TKAgg 或 Qt5Agg 后端

    我在 Ubuntu 16 04 上使用 Matplotlib 2 0 和 Python 3 6 来创建数据图 电脑显示器的分辨率为 4k 分辨率为 3840x2160 绘图数字看起来非常小 字体也很小 我已经尝试过TKAgg and Qt5
  • 将二进制数据视为文件对象?

    在此代码片段 由另一个人编写 中 self archive是一个大文件的路径并且raw file是以二进制数据形式读取的文件内容 with open self archive rb as f f seek offset raw file s
  • Django 中使用外键的抽象基类继承

    我正在尝试在 Django 支持的网站上进行模型继承 以遵守 DRY 我的目标是使用一个名为 BasicCompany 的抽象基类来为三个子类提供通用信息 Butcher Baker CandlestickMaker 它们位于各自的应用程序
  • 关闭正在运行代码的 IPython Notebook

    怎么运行的 我在 IPython Notebook 中运行了一些代码 一些迭代工作 我不小心关闭了正在运行的笔记本的浏览器 但回到 IPython 仪表板 我发现这个特定的笔记本尚未关闭 所以如果我再次打开笔记本 我会在它正在执行的代码前面
  • 如何仅读取 CSV 文件每行的第一列 [重复]

    这个问题在这里已经有答案了 如何在Python中读取CSV文件每行的第一列 我的数据是这样的 1 abc 2 bcd 3 cde 我只需要循环第一列的值 另外 当我在 calc 中打开 csv 文件时 每行中的数据都在同一个单元格中 这正常
  • 将二进制数转换为包含每个二进制数的数组

    我试图将二进制值转换为每个 1 0 的列表 但我得到默认的二进制值而不是列表 我有一个字符串 我将每个字符转换为二进制 它给了我一个列表 其中每个字符都有一个字符串 现在我试图将每个字符串拆分为值为 0 1 的整数 但我什么也得不到 if
  • 美丽的汤刮 - 登录凭据不起作用

    尝试使用登录凭据抓取页面 payload email gmail com password urls login url https www spotrac com signin url https www spotrac com nba

随机推荐

  • 不唯一的表/别名

    我收到错误ERROR 1066 42000 Not unique table alias 我不知道出了什么问题 SELECT Project Assigned ProjectID Project Title Account Account
  • TensorFlow 目标检测 API 的非极大值抑制

    我正在 Tensorflow 对象检测 API 中实现 Faster RCNN v2 Inception 为了消除冗余重叠检测 我读到应该应用 NMS 一种方法是调整配置文件中的 NMS IOU 阈值first stage nms iou
  • JavaScript 运行时如何表示闭包和作用域

    这主要是出于好奇而提出的问题 考虑以下函数 var closure function f0 var x new BigObject var y 0 closure function return 7 function f1 var x Bi
  • 绑定到 Twitter Bootstrap 3 中的 Collapse 事件

    假设我有 Bootstrap Collapse div class panel group div class panel panel default div class panel heading h4 class panel title
  • 错误:入口点不在当前项目内

    无法从 Android Studio 运行 flutter 未检测到 flutter 项目 其显示错误 入口点不在当前项目内 每次重新启动 android studio 时都会显示相同的错误消息 删除 ideaflutter 项目根目录下的
  • 使用 UIWebView 进行手势识别

    我在我正在构建的应用程序中设置了一些手势识别功能 其中一种手势是单指单击 它会隐藏屏幕顶部的工具栏 效果很好 除了一件事 点击链接也会导致工具栏消失 是否可以检测到不是链接点击的点击 我可以通过查看点击发生的位置来做到这一点 并且仅在 ht
  • 如何正确使用insertRowsAtIndexPaths?

    我浏览了在线的所有示例 但无法弄清楚如何正确地将单元格添加到带有动画的表格视图中 假设我有一个包含一个单元格的部分 当用户单击第一个单元格的附件时 我想添加另一个单元格 我的 添加 方法执行以下操作 IBAction toggleEnabl
  • Qt状态栏颜色

    我将 Qt 与 Python 结合使用 并且有一个底部带有状态栏的主窗口 我可以使用 QLabel 在栏中显示一条消息 并使用类似的方法设置该消息的颜色 font color In progress font 对于 QLabel 文本 我还
  • GO - 本地导入不起作用

    我是 golang 新手 我想构建我的第一个简单的 Web 应用程序 每次我想构建源代码时 都会收到错误locale import controllers in non local package 这是我的文件夹结构 goTest Dock
  • 在arm64上安装构建工具不起作用

    我一直在尝试安装sdkmanager build tools 30 0 2 在arm64处理器 安培CPU 上 但每次我得到这个 Warning Dependant package with key emulator not found W
  • 如何通过 apache 渲染 .phtml 文件

    我想通过 Apache 渲染 phtml 文件 但是当我尝试时 它会将页面渲染为文本而不是 html 在我的虚拟主机配置中 如果我尝试渲染index php 它会正确执行 但是 当我将 DirectoryIndex 更改为 index ph
  • 如何通过asp.net mvc中的api调用将文件上传到服务器上

    public ActionResult Index PublishPost post HttpPostedFileBase file var apiURL http test sa com rest social update 1161 u
  • 内核清零内存?

    我正在使用 Debian squeeze 并注意到内存总是归零 这是 Linux 发行版中的新功能吗 前段时间 我相信我可以使用 put 并且会输出垃圾 我多次运行这个测试程序 但注释的结果总是相同的 我在 sysctl conf 中有 r
  • 如何根据谷歌地图中标记的相对位置制作多边形?

    我有一个标记列表 我想在其周围创建一个多边形 显示标记周围的区域 而不是标记本身 因此 我希望多边形 包裹 在标记周围以显示它们周围的相对区域 而不是让多边形点成为标记的直接纬度 经度 关于我如何完成这样的事情有什么想法吗 这被称为凸包 有
  • 需要对开发者控制台上的 beta/alpha 测试进行一些说明

    背景 Android 开发者控制台有 3 个选项卡用于发布应用程序的 apk 文件 alpha beta 和 production 如下所示 我记得在一次 Google IO 讲座中 在进行 100 规模发布之前检查应用程序的好坏的一个很酷
  • 单击网格中的 LinkBut​​ton 时避免页面刷新

    我有一个GridView控件 并且在该控件内部我使用定义了一个链接按钮GridView ItemTemplate 我用它来点击打开一个新窗口 但是 当我单击链接按钮时 页面会在打开新窗口之前刷新 单击链接按钮后如何阻止页面刷新 当我将更新面
  • D3 网格中的力模拟

    我想知道如何修改Mike Bostock 的多力布局示例 https bl ocks org mbostock 1021841为了尝试获得强制布局以对网格中的节点进行分组 让我们假设我们有以下 csv Name Category1 Cate
  • 从字符串创建可变长度数组

    字符串 string a b c d 应该创建一个像这样的数组 array a gt array b gt array 我想出了这个 function create array arr string data parts explode s
  • Webpack 警告:您可能需要适当的加载器来处理此文件类型 (date-nfs)

    我的应用程序有问题 我有一个网站 我使用 date fns 根据用户语言显示格式化日期 它工作得很好 但我更新了 date fns 从那以后我收到了一个警告 在我的 JavaScript 代码中我使用 const locale requir
  • 尝试/捕获或验证速度?

    我正在使用 Python 每当我必须验证函数输入时 我都会假设输入有效 然后捕获错误 就我而言 我有一个通用的Vector 我用它来做一些不同的事情 其中 之一就是加法 它的功能既是Color 类并作为Vector 所以当我向Color 它