ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python – 通过从列表复制到numpy数组来加速cython循环

2019-06-29 12:45:01  阅读:216  来源: 互联网

标签:python numpy cython bloom-filter


我正在编写一些性能密集型代码,并希望从cythonistas那里得到一些关于如何进一步改进它的反馈.我写的函数的目的有点难以解释,但他们所做的并不是那么令人生畏.第一个(粗略地)采用两个数字列表的字典并将它们连接起来以获得一个数字列表的字典.它只运行一次所以我不太关心优化它.第二个调用第一个,然后使用其结果基本上将存储在numpy数组中的索引与数组列表中的数字交叉,以在(pybloomfiltermmap)bloom过滤器上形成查询(新数字).

我已经确定了沉重的步骤是由于我的嵌套循环并减少了使用的循环次数,从循环中移出了所有只需要发生一次的东西,然后根据我的知识键入所有内容.尽管如此,第二个函数中i的每次迭代大约需要10秒,这太过分了.我仍然在html编译输出中看到黄色的主要内容是由于列表和numpy数组中的索引访问,所以我尝试用所有numpy数组替换我的列表但是无法获得任何改进.我非常感谢您提供的任何反馈.

#cython: boundscheck=False
#cython: wraparound=False

import numpy as np
cimport numpy as np

def merge_dicts_of_lists(dict c1, dict c2):
    cdef dict res
    cdef int n, length1, length2, length3
    cdef unsigned int i, j, j_line, jj, k, kk, new_line

    res =  {n: [] for n in range(256)}
    length1 = len(c1)

    for i in range(length1):
        length2 = len(c1[i])
        for j in range(length2):
            j_line = c1[i][j]
            jj = (j_line) % 256
            length3 = len(c2[jj]) 
            for k in range(length3):
                kk = c2[jj][k]
                new_line = (j_line << 10) + kk
    res[i].append(new_line)
    return res


def get_4kmer_set(np.ndarray c1, dict c2, dict c3, bf):
    cdef unsigned int num = 0
    cdef unsigned long long query = 0
    cdef unsigned int i, j, i_row, i_col, j_line
    cdef unsigned int length1, length2
    cdef dict merge 
    cdef list m_i 

    merge = merge_dicts_of_lists(c2, c3)
    length1 = len(c1[:,0])
    for i in range(length1):
        print "i is %d" % i
        i_row = c1[i,0]
        i_col = c1[i,1]
        m_i = merge[i_col]
        length2 = len(m_i)
        for j in range(length2):
            j_line = m_i[j]
            query = (i_row << 24) + (i_col << 20) + j_line
            if query in bf:
                num += 1
    print "%d yes answers from bf" % num

解决方法:

为了后人的缘故,我正在添加一个非主题的答案,但我希望它对某些人有用.我上面发布的代码与我决定保留的代码差别不大,因为它已经编译为Ctyhon html编译输出所见的短C行.

由于最里面的操作是Bloom过滤器查询,我发现最有帮助的是以两种方式加速该步骤.一个是将pybloomfiltermmap使用的哈希函数更改为murmurhash3的可用C实现.我发现pybloomfilter正在使用sha,这对于加密哈希函数来说是比较慢的.第二个提升来自应用本文中的技巧:http://www.eecs.harvard.edu/~kirsch/pubs/bbbf/rsa.pdf.基本上,它表示你可以通过使用两个哈希值的线性组合而不是BF的不同哈希值来节省大量计算.这两个技巧一起使查询时间提高了一个数量级(~5x).

标签:python,numpy,cython,bloom-filter
来源: https://codeday.me/bug/20190629/1326125.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有