为什么 __getitem__(key) 和 get(key) 明显慢于 [key]?

2024-02-24

据我了解,括号只不过是一个包装器__getitem__。以下是我对此进行基准测试的方法:

首先,我生成了一个半大字典。

items = {}
for i in range(1000000):
    items[i] = 1

然后,我使用cProfile测试了以下三个功能:

def get2(items):
    for k in items.iterkeys():
        items.get(k)

def magic3(items):
    for k in items.iterkeys():
        items.__getitem__(k)

def brackets1(items):
    for k in items.iterkeys():
        items[k]

结果看起来像这样:

         1000004 function calls in 3.779 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    3.779    3.779 <string>:1(<module>)
        1    2.135    2.135    3.778    3.778 dict_get_items.py:15(get2)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
  1000000    1.644    0.000    1.644    0.000 {method 'get' of 'dict' objects}
        1    0.000    0.000    0.000    0.000 {method 'iterkeys' of 'dict' objects}


         1000004 function calls in 3.679 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    3.679    3.679 <string>:1(<module>)
        1    2.083    2.083    3.679    3.679 dict_get_items.py:19(magic3)
  1000000    1.596    0.000    1.596    0.000 {method '__getitem__' of 'dict' objects}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.000    0.000    0.000    0.000 {method 'iterkeys' of 'dict' objects}


         4 function calls in 0.136 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.136    0.136 <string>:1(<module>)
        1    0.136    0.136    0.136    0.136 dict_get_items.py:11(brackets1)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.000    0.000    0.000    0.000 {method 'iterkeys' of 'dict' objects}

问题出在我进行基准测试的方式上吗?我尝试用简单的“pass”替换括号访问,以确保数据确实被访问,并发现“pass”运行得更快。我对此的解释是数据确实正在被访问。我还尝试附加到一个新列表,它给出了类似的结果。


首先是Not_a_Golfer贴出的反汇编:

>>> d = {1:2}
>>> dis.dis(lambda: d[1])
  1           0 LOAD_GLOBAL              0 (d)
              3 LOAD_CONST               1 (1)
              6 BINARY_SUBSCR       
              7 RETURN_VALUE   

>>> dis.dis(lambda: d.get(1))
  1           0 LOAD_GLOBAL              0 (d)
              3 LOAD_ATTR                1 (get)
              6 LOAD_CONST               1 (1)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE  

>>> dis.dis(lambda: d.__getitem__(1))
  1           0 LOAD_GLOBAL              0 (d)
              3 LOAD_ATTR                1 (__getitem__)
              6 LOAD_CONST               1 (1)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE

现在,正确进行基准测试对于将任何内容解读到结果显然很重要,但我的了解还不够,无法提供太多帮助。但假设确实存在差异(这对我来说是有意义的),以下是我对为什么存在差异的猜测:

  1. dict.get只是“做更多”;它必须检查密钥是否存在,如果不存在,则返回其第二个参数(默认为None)。这意味着存在某种形式的条件或异常捕获,因此我完全不感到惊讶,这与检索与键关联的值的更基本操作具有不同的时序特征。

  2. Python 有一个用于“订阅”操作的特定字节码(如反汇编中所示)。内置类型包括dict,主要用 C 实现,它们的实现不一定遵循正常的 Python 规则(只需要它们的接口,而且即使在那里也有很多极端情况)。所以我的猜测是,实施BINARY_SUBSCR操作码或多或少directly到支持此操作的内置类型的底层 C 实现。对于这些类型,我希望它实际上是__getitem__它作为 Python 级别的方法存在以包装 C 实现,而不是括号语法调用 Python 级别的方法。

基准测试可能很有趣thing.__getitem__(key)反对thing[key]对于实现的自定义类的实例__getitem__;您实际上可能会看到相反的结果BINARY_SUBSCR操作代码在内部必须回退到执行与查找方法并调用它相同的工作。

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

为什么 __getitem__(key) 和 get(key) 明显慢于 [key]? 的相关文章

  • 使用 pdfkit 和 FastAPI 下载 PDF 文件

    我将使用 FastAPI 创建一个 API 将HTML页面到 PDF 文件 使用pdfkit 但是 它将文件保存到我的本地磁盘 当我在线提供此API后 用户如何将该PDF文件下载到他们的计算机上 from typing import Opt
  • 配置 PIP 以在代理后面工作

    我已经安装了 python 3 4 3 附带pip 我想从代理后面使用 pip 所以我执行了以下操作 Created C Users foo pip pip ini并添加了代理配置部分 proxy export http proxy my
  • 让 Django 提供可下载文件

    我希望网站上的用户能够下载路径被遮挡的文件 因此无法直接下载它们 例如 我希望 URL 是这样的 http example com download f somefile txt 在服务器上 我知道所有可下载的文件都位于该文件夹中 home
  • Native TF 与 Keras TF 性能比较

    我使用本机和后端张量流创建了完全相同的网络 但在使用多个不同参数进行了多个小时的测试后 仍然无法弄清楚为什么 keras 优于本机张量流并产生更好 稍微但更好 的结果 Keras 是否实现了不同的权重初始化方法 或者执行除 tf train
  • 打开文件路径在 python 中不起作用[重复]

    这个问题在这里已经有答案了 我正在编写一个数据库程序 personica 是我的测试主题 我通常在文件路径的位置有一个变量 但出于测试和演示的目的 我只有一个字符串 在我的计算机上的这个确切位置有一个文本文件 顺便说一句 因为我很偏执 所以
  • NLTK:包错误?朋克和泡菜?

    基本上 我不知道为什么会收到此错误 只是为了获得更多图像 这里有一个代码格式的类似消息 由于是最新的 该帖子的答案已经在消息中提到 Preprocessing raw texts LookupError Traceback most rec
  • 如何使用 django Rest 框架保存多对多字段对象

    我有博客 发布 标签三个模型 在博客模型中 我将字段 postedin 作为发布模型的外键 将 标签 作为标签模型的许多字段 模型 py class Posted models Model name models CharField Pos
  • 如何使用格式保存 Tkinter 文本小部件的内容

    我在 python 中使用 Tkinter 在文本窗口中显示输出 我发现使用 get 功能我可以从此窗口检索文本内容 但我有用不同背景颜色标记的文本部分 是否可以将内容与这些颜色一起复制到文件 例如 html 或 doc 中 没有对你想要的
  • R.scale() 和 sklearn.preprocessing.scale() 之间的区别

    我目前正在将数据分析从 R 转移到 Python 当在 R 中缩放数据集时 我将使用 R scale 根据我的理解 它将执行以下操作 x mean x sd x 为了替换该函数 我尝试使用 sklearn preprocessing sca
  • Python 中 eval("input()") 和 eval(input()) 之间的区别

    我正在尝试以下功能 x eval input 输入为 123 x 的类型也是int 它工作正常 In 22 x eval input enter enter 123 In 24 print type x
  • 如何在 Django 中像应用程序一样从配置中注册 Flask 蓝图?

    如何从我的配置中注册 Flask 蓝图 就像 Django 中的应用程序一样 我想在配置文件中定义蓝图 它将自动注册 config py BLUEPRINTS news files 实际上我一直在一个暂定名为的项目中勾勒出类似的东西臀部口袋
  • Python3 - 如何将字符串转换为十六进制

    我正在尝试将字符串逐个字符转换为十六进制 但我无法在Python3中弄清楚它 在较旧的 python 版本中 我的以下内容有效 test This is a test for c in range 0 len test print 0x s
  • 如何检查discord.py中的所有者

    我试图让这个命令只有所有者才能运行它 是否有办法检查服务器的最高角色或创建者 我尝试了 commands is owner 但这仅检查某人是否是机器人的所有者 Guild owner https discordpy readthedocs
  • 在 Python 中通过网络发送对象的最佳方式是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我需要通过网络发送对象 我将使用 Twisted 并且我刚刚开始查看它的文档 据我所知 python实现套接字的唯一方式是通过文本 那么我如何使
  • Scrapy FakeUserAgentError:获取浏览器时发生错误

    我使用 Scrapy FakeUserAgent 并在我的 Linux 服务器上不断收到此错误 Traceback most recent call last File usr local lib64 python2 7 site pack
  • Python 中的 Firebase 身份验证时出现 KeyError:“databaseURL”

    相信你做得很好 我是 firebase 的新手 正在尝试进行用户身份验证 我已经安装了pyrebase4并在firebase控制台上创建了一个项目 我还启用了使用 电子邮件和密码 登录并尝试连接我的应用程序 下面是我正在尝试的代码 impo
  • 获取列的 [0, x] 元素的最小值

    我需要计算一列 其中值是对其他列进行矢量化运算的结果 df new col df col1 min 0 df col2 然而 事实证明我不能像上面的语法一样使用 min 那么 获得 pandas 列的零和给定值之间的最小值的正确方法是什么
  • 启动客户端时,代码要求提供电话/机器人令牌

    使用 Telethon 库运行我的第一个代码时 它要求提供机器人令牌 这是实际的代码 from telethon import TelegramClient events sync api id 1234567 api hash xxxxx
  • Hoare Partitioning算法讲解

    根据许多网站给出的伪代码 我写了这个Hoare分区算法 它采用一个数组 根据给定的主元来分区子数组的开始和结束索引 它工作得很好 但是有人可以解释一下逻辑 它是如何做到这一点的吗 这是代码 def hoare arr start end p
  • Pandas 数据框可对多列和要列出的值进行字典

    我有一个数据框 id key a1 1 a2 1 a3 1 a4 2 a5 2 a6 3 我想创建一本字典key作为机器号 并且id列作为列表 like 1 a1 a2 a3 2 a4 a5 3 a6 我可以先使用 groupby 然后再使

随机推荐

  • 将列表中的元素替换为另一个列表中的元素

    如何替换 a 中的元素list和另外一个 例如我想要所有two成为one 您可以使用 Collections replaceAll list two one From 文档 http docs oracle com javase 7 doc
  • 更新 mobx 中的状态时组件不会重新渲染

    我试图理解为什么当我更改 mobx 可观察名称数组中的状态时我的应用程序没有重新渲染 我正在使用输入标签更改值 希望得到一些帮助 观察者部分 import observable action autorun computed from mo
  • 无法在初始化程序中访问实例成员“widget”

    在我的项目中 我使用以下代码将数据从一个小部件传递到另一个小部件 Navigator push context MaterialPageRoute builder context gt TranslatorSignUpStep2 trans
  • 如何使用Python打开ppt文件

    我想在linux上使用Python打开一个ppt文件 就像python打开一个 txt文件 我知道win32com 但我正在linux上工作 那么 我需要做什么 python pptx https python pptx readthedo
  • 我的 Zend 框架“引用”混乱

    我有一个可能非常简单的问题 在 Zend Framework 手册或其他地方找不到令人满意的 主观看到的 答案 有很多方法可以将我的 php 变量移交给我的 sql 查询 以至于我失去了概述 并且可能我对一般引用缺乏一些理解 准备好的报表
  • 带回溯的数独求解算法

    我正在寻求实现一种非常简单的算法 该算法使用强力回溯来解决数独网格 我面临的问题是 在我的实现中 我包含了两个实例变量Sudoku类称为row and col 对应于表示数独网格的二维数组中空单元格的行和列 When my solve 方法
  • CodeIgniter 和 HMVC 问题

    首先 对这篇文章造成的任何不便表示歉意 因为这是我第一次在这里发布问题 我需要更多时间来适应这个问题 Q1 我想创建 2 个 主控制器 FrontEnd and BackEnd像这样 MY 控制器延伸CI 控制器 FrontEnd延伸MY
  • 对象字面量中属性名称周围的方括号意味着什么?

    我用JS写了一段时间了 还没有使用过这种形式 dist files bpr lib Monster min js the 它有效 我只是以前没有使用过或见过它 最近才使用 ES6 它们被称为 计算属性名称 From MDN https de
  • java中不使用乘法、除法和取模运算符来除两个整数

    我写了一个代码 该代码在将两个数字相除后找出商 但不使用乘法 除法或取模运算符 My code public int divide int dividend int divisor int diff 0 count 0 int fun di
  • 如何为 Android 启用 AllOpen 插件

    我正在尝试添加allopen https kotlinlang org docs reference compiler plugins html all open compiler plugin安卓插件 我把这个添加到我的build gra
  • 用于查找计划任务向导任务信息的脚本

    我知道有一个命令可以查找计算机的计划任务 但我想获取有关计划任务本身的更多信息 我想知道计划任务的执行时间和时间以及计划任务的名称和区域 有任何想法吗 Set TS CreateObject Schedule Service TS Conn
  • python,flask,网络应用程序安全[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在 Flask 上部署时 我想从 Web 应用程序编辑 sqlite 数据库 并且遇到了 chmod 权限问题 因此我只是让 root 以
  • 在 LESS 中生成供应商前缀

    我已经将这种方法拼凑在一起 使用 LESS 生成供应商前缀的属性和动画 首先是一些工厂函数 vendorprefix property value webkit property value moz property value ms pr
  • 使用 shell 脚本制作文件的多个副本

    我正在尝试编写一个小型 shell 脚本来制作文件的多个副本 我可以将文件名作为输入 但不能将副本数作为输入 这是我写的 但我无法通过NUMBER变量到for循环 echo n Enter filename read FILENAME ec
  • 编辑文本框中提示的自定义位置。

    我想知道是否有任何方法可以在 编辑文本 视图的底部获得提示 然后用户开始在框的顶部输入文本 作为一个额外的问题 有什么办法可以让提示在用户开始输入文本后不会消失 您可以使用 gravity 属性设置文本的位置 如http developer
  • 无法通过在 JavaScript 中识别对象的父 ID 将对象推入父数组

    我有一个 JSON 数组 其属性为 id 和parentActivityId scope data id 1 activityName Drilling parentActivityId 0 items id 2 activityName
  • 有人能用例子解释一下java EE中的演示层.业务层.集成层这些词吗?

    Java EE 中的这些是什么 表示层 商业层 集成层 我想通过示例了解这些模式是什么 表示层 用户看到的内容 通常是 Web 应用程序 业务层 应用程序的所有逻辑都在其中执行 集成层 将系统连接到其他系统的层 通过数据库连接 JMS We
  • Java Getter 和 Setter

    在 Java 中是否有更好的标准方法来创建 getter 和 setter 必须为每个变量显式定义 getter 和 setter 这是相当冗长的 有没有更好的标准注释方法 Spring有这样的东西吗 即使 C 也有属性 我不确定你是否会认
  • 在 React 中使用 .map() 时处理空数组

    我有一个 React JS 组件 它将映射notes要显示的变量 然而 我遇到了没有笔记并收到错误的问题 解决这个问题的正确方法是什么 这是代码 import React Component from react class List ex
  • 为什么 __getitem__(key) 和 get(key) 明显慢于 [key]?

    据我了解 括号只不过是一个包装器 getitem 以下是我对此进行基准测试的方法 首先 我生成了一个半大字典 items for i in range 1000000 items i 1 然后 我使用cProfile测试了以下三个功能 de