Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python/cython中绝对最快的查找_Python_C_Performance_Optimization_Cython - Fatal编程技术网

python/cython中绝对最快的查找

python/cython中绝对最快的查找,python,c,performance,optimization,cython,Python,C,Performance,Optimization,Cython,我想做一个32位整数=>32位整数的查找映射 输入键不需要连续,也不包含2^32-1(我也不希望内存中的输入键占用那么多空间!) 该用例适用于扑克评估器,因此查找必须尽可能快。完美的散列很好,但可能有点超出范围 我觉得答案是某种cython解决方案,但我不确定cython的基础,以及它是否真的对Python的dict()type有好处。当然,只有一个简单的偏移跳转的平面数组会非常快,但是我正在为表分配2^32-1内存中的位置,这是我不想要的 有什么建议/策略吗?绝对速度和最小内存占用是目标。您没

我想做一个32位整数=>32位整数的查找映射

输入键不需要连续,也不包含2^32-1(我也不希望内存中的输入键占用那么多空间!)

该用例适用于扑克评估器,因此查找必须尽可能快。完美的散列很好,但可能有点超出范围

我觉得答案是某种cython解决方案,但我不确定cython的基础,以及它是否真的对Python的
dict()
type有好处。当然,只有一个简单的偏移跳转的平面数组会非常快,但是我正在为表分配
2^32-1
内存中的位置,这是我不想要的


有什么建议/策略吗?绝对速度和最小内存占用是目标。

您没有足够的智能来编写比dict快的东西。不要难过;地球上99.99999%的人不是。使用
dict

您正在描述一个哈希索引集合的完美用例。您还描述了一个完美的场景,即先写后优化的策略

因此,从Python
dict
开始。它的速度很快,绝对可以完成你需要的工作

然后对其进行基准测试。弄清楚它需要走多快,离你有多近。然后是三个选择

  • 够快了。你完了
  • 它几乎足够快,比如说在大约2倍的范围内。编写自己的哈希索引,注意哈希函数和冲突策略
  • 太慢了。你死定了。没有什么简单的东西能让你进步10倍或100倍。至少你没有浪费时间在一个更好的散列索引上

  • 首先,在你做任何其他事情之前,你应该定义“足够快”对你意味着什么。你总是可以做得更快,所以你需要设定一个目标,这样你就不会发疯。这个目标是双头的,这是完全合理的,比如“映射查找必须在这些参数(min/max/mean)中执行,当/如果我们达到这些数字,我们愿意花费X个多小时的开发时间来进一步优化,但我们会停止。”


    第二,为了加快速度,您应该做的第一件事是复制Cpython源代码树中
    Objects/dictobject.c
    中的代码(创建类似
    intdict.c
    之类的新代码),然后对其进行修改,使键不是python对象。追求更好的散列函数可能不会很好地利用整数时间,但消除对键的
    INCREF/DECREF
    PyObject\u richcomarebool
    调用将是一个巨大的胜利。由于您不删除键,您还可以省去对伪值的任何检查(这些伪值的存在是为了保留已删除项的冲突遍历),尽管您可能只需对新对象进行更好的分支预测,就可以免费获得大部分胜利。

    如果有帮助,初始化后的密钥空间是完全静态的-不需要插入。不会改变任何东西。对于许多非常特定的用例,编写比标准
    dict
    更快的东西并不难,甚至可以将dict实现本身作为一个新对象进行优化和公开
    dict
    对于一般用例来说是极好的和合理的最佳选择,但这意味着几乎每一个特定的使用都会受到惩罚(可能除了一般的字符串哈希,dict非常擅长)。“内存最小的绝对速度”:你知道这里没有最佳选择,是吗?它需要一个令人满意的工程权衡,即(根据定义)产生一个或两个次优选择。如果内存太大,那么模块
    sqlite3
    可能是您最好的简单选择。您知道映射将有多少个条目吗?您是否愿意牺牲初始创建时间以加快查找速度?此外,“绝对速度”对您意味着什么?在表的整个生命周期(包括创建时间)内消耗的CPU总周期,或者仅用于查找的周期?@NickBastin:初始创建时间不是问题,只是用于查找的时间。该表最多可以有1.33亿个条目。如果瓶颈是
    int
    int
    映射,您应该使用PyPy和标准pypypy
    dict
    。你是说《代码》中的cython源代码吗?在
    https://github.com/cython/cython
    ?我似乎在那里找不到
    Objects/dictobject.c
    文件,即使使用搜索…也找不到“cpython”源代码—python本身的源代码(c实现)。您可以从默认的
    dict
    对象开始,只需调整它以使其更快。