Cython:类似 CPP 字典的地图性能

2024-04-14

我一直在比较使用模仿 python 字典的 c++ 映射与在 cython 中使用普通 python 字典的性能。我在 sklearn 中编写了“fast_dict”实现的(简化)变体(https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/utils/fast_dict.pyx https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/utils/fast_dict.pyx)。与 fast_dict 文档字符串中的注释一致,在 cpp 情况下,映射创建速度要慢得多,但查找也是如此(我预计会更快)。

我的实现基本上如下所示(很大程度上来自 sklearn 实现,但经过修改以涉及 Int->Int 的映射):

from libcpp.map cimport map as cpp_map
from cython.operator cimport derefernce as deref

cdef class IntDict:

    def __init__(self,dict orig_dict={}):
        """loads from an ordinary dict directly"""
        for key,val in orig_dict.iteritems():
            self.my_map[key] = val

    def __setitem__(self, int key, int value):
        self.my_map[key] = value

    def __getitem__(self, int key):
        cdef cpp_map[ITYPE_t,ITYPE_t].iterator it = self.my_map.find(key)
        if it == self.my_map.end():
            raise KeyError('%d' % key)
        return deref(it).second

.pxd 文件如下所示(同样,主要来自 sklearn):

DTYPE = np.float64
ctypedef np.float64_t DTYPE_t

ITYPE = np.intp
ctypedef np.intp_t ITYPE_t

cdef class IntDict:
    cdef cpp_map[ITYPE_t,ITYPE_t] my_mapenter

以下是我设计的测试:

cpdef load_ord_dict(r=100000):
    cdef dict d = {}
    cdef int i,size = len(range(r))

    for i in range(size):
        d[i] = 0

    return d

cpdef load_cpp(r=100000):
    cdef IntDict d = IntDict()
    cdef int i,size = len(range(r))

    for i in range(size):
        d[i] = 0

    return d

cpdef lookup_ord(dict d,r=100000):
    cdef int i,size = len(range(r))

    for i in range(size):
       d[i]

cpdef lookup_cpp(IntDict d,r=100000):
    cdef int i,size = len(range(r))

    for i in range(size):
       d[i]

结果(在linux机器上测试,在我的mac上结果类似):

In [3]: timeit(load_ord_dict())
100 loops, best of 3: 4.3 ms per loop

In [4]: timeit(load_cpp())
10 loops, best of 3: 21.7 ms per loop

In [5]: d1 = load_ord_dict()

In [6]: timeit(lookup_ord(d1))
100 loops, best of 3: 3.95 ms per loop

In [7]: d2 = load_cpp()

In [8]: timeit(lookup_cpp(d2))
100 loops, best of 3: 11.8 ms per loop

有想过为什么 cpp 版本这么慢吗?我在这里做错了什么吗?

更新:我按照下面的建议为 unordered_map 添加了相同的测试。性能似乎介于字典和有序映射之间:

from libcpp.unordered_map cimport unordered_map as umap

cdef class UnOrdIntDict:

    def __init__(self,dict orig_dict={}):
        for key,val in orig_dict.iteritems():
            """exchange cpp_map[..] in pxd with umap[..] in this case"""
            self.my_map[key] = val

    def __setitem__(self, int key, int value):
        self.my_map[key] = value

    def __getitem__(self,int key):
        """I'm assuming that this works like the ordinary cpp_map"""
        cdef umap[ITYPE_t,ITYPE_t].iterator it = self.my_map.find(key)
        if it == self.my_map.end():
            raise KeyError('%d' % key)
        return deref(it).second


   cpdef load_cpp_unordered(r=100000):
       cdef UnOrdIntDict d = UnOrdIntDict()
       cdef int i,size = len(range(r))

       for i in range(size):
           d[i] = 0

       return d

   cpdef lookup_cpp_unordered(UnOrdIntDict d,r=100000):
       cdef int i,size = len(range(r))

       for i in range(size):
           d[i]

结果:

In [3]: timeit(load_cpp_unordered())
10 loops, best of 3: 29.8 ms per loop

In [4]: timeit(lookup_cpp_unordered(d3))
100 loops, best of 3: 8.23 ms per loop

None

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

Cython:类似 CPP 字典的地图性能 的相关文章

随机推荐

  • 硒,是否存在多种元素之一?

    以答案为基础如何使用 Selenium for Python 等待页面加载 https stackoverflow com questions 26566799 how to wait until the page is loaded wi
  • 如何获取 Mac(Cocoa 或 C)的电池电量(以 mWh(而非百分比)为单位)

    标题几乎解释了一切 我正在创建一个 Mac 应用程序 我需要电池电量具体单位为毫瓦时 不是百分比 最好用 C 或 Objective C 来做 Thanks 抱歉 但我认为硬件没有办法报告这一点 随着电池进入其生命周期 它会随着时间的推移而
  • 以 json 形式返回时排除某些字段

    我有一个 ASP NET Web API 应用程序 现在假设应用程序由 User 实体和 Post 实体组成 帖子是由用户编写的 因此每个帖子实体都包含对用户实体的引用 class Post public int Id get set pu
  • android 列表视图按钮

    我正在尝试在列表视图中添加一个按钮 但按钮没有显示 我正在使用 json 解析从我的服务器获取数据 我正在使用哈希图和列表视图 此外 我也无法在列表视图中添加按钮 这是我的代码 package acb xiynove import java
  • 使用 Open Graph API 阻止用户

    是否可以使用开放图谱 API 阻止 Facebook 上的用户 我不想阻止用户使用应用程序 但希望允许用户在我的应用程序中阻止 Facebook 好友 如果他们愿意 这与访问 Facebook com 并阻止用户一样 从而将他们隐藏在您的所
  • ADO 参数化查询不返回任何结果

    我正在使用此查询从经典 asp 页面中的 vbscript 获取一些结果 但它不会返回任何值 该页面是空白的 也没有错误 请问有什么建议吗 dim cmd admin no admin no request QueryString admi
  • Sammy.js 使用 &,? 读取路由

    需要的路线看起来像 routeName param1 aaaa param2 bbb 添加到萨米 routeName param1 param2 and routeName param1 param2 他们都不起作用 我自己一直在 Samm
  • AVAssetExportSession - 在 IOS 中加入 2 个 mp4 文件

    我正在尝试使用以下代码在 ipad 2 上将 2 个预先存在的 mpeg 4 视频连接在一起 void mergeTestVideos setup asset NSString firstassetpath NSString stringW
  • Spring Tool Suite 找到 spring-boot 集成测试配置并且不启动主应用程序

    我在使用 Spring Tool Suite 与 spring boot 时遇到了一些困难 我创建了一个自定义 Maven spring boot web application 其中包括多个 JUnit 测试 其中一个测试是集成测试 它具
  • 建模单个子表/多个父表

    我正在努力对共享单个表 子表 的多个表 父表 之间的关系进行建模 给定以下父表1 其他父表2 3等类似 Entity Table name parent1 public class ParentEntity1 Id Column name
  • 如何装饰可调用类的实例?

    def decorator fn def wrapper args kwargs print With sour cream and chives return fn args kwargs return wrapper class Pot
  • 为什么 Nokogiri 没有安装?

    我在安装 Nokogiri 时遇到问题 当我跑步时bundle install or gem install nokogiri安装失败 我收到的错误是 注 此失败是由于使用nokogiri org上的安装命令造成的 Building nat
  • 如何结束谈话?

    我已经使用 Bot Framework 创建了一个机器人 并且正在使用conversationID用我的后端对话引擎维护状态 我在文档中找不到用于结束对话的信息 至关重要的是 在某些时候 用户能够发出对话 结束或退出 的信号 以便下次他们开
  • 如何跨域使用 SignalR

    我正在尝试将 SignalR 与跨域一起使用 但在调用启动函数时收到错误消息 错误信息是 Uncaught TypeError Cannot call method start of undefined 我正在使用代码 服务器端 assem
  • 已编译的Azure功能监控:“没有可用数据”

    我在 Azure 上使用几个编译的 C 函数 它们按预期工作 但是当我单击任一功能上的 监视 时 它只显示 无可用数据 我可以在 开发 选项卡的日志上看到该函数正在运行 但希望了解该函数的用法的概述 我有什么遗漏的吗 我也看到这些了我将一个
  • jQuery 上一个按钮在单击时返回到 Q。) 1 而不是一一向后退

    jQuery 上一个按钮无法按预期工作 基本上最好的解释方法是 如果我在回答问题 5 时单击上一个按钮 则它默认为问题 1 而不是问题 4 所以它默认为问题1 这是一个问题 该怎么办 jQuery 位于脚本标签的底部 if i Questi
  • 如何为 docker 容器的日志着色

    我有一个容器 有时在日志中写入对我来说很重要的关键字 我想在终端中以颜色突出显示该单词 但同样重要的是仍然实时查看所有内容日志 follow 我刚刚尝试过命令 docker logs f my app tail 100 grep color
  • 大于100,000的随机数

    我正在用 C C 编写 我想创建很多大于 100 000 的随机数 我该怎么做呢 和rand 你不会那样做rand 但使用较新的 C 附带的适当随机数生成器 请参见例如cppreference com http en cppreferenc
  • Eclipse android ADT安装问题

    我按照每个步骤使用 Eclipse IDE 安装 android ADT 插件 我在 Windows 7 计算机上安装了 Eclipse for Java 我遵循每一步 尽管做了所有的事情 我还是收到以下错误 没有人犯过这个错误 我很着急请
  • Cython:类似 CPP 字典的地图性能

    我一直在比较使用模仿 python 字典的 c 映射与在 cython 中使用普通 python 字典的性能 我在 sklearn 中编写了 fast dict 实现的 简化 变体 https github com scikit learn