我正在用 Python 和 R 编写一个与 Rpy2 桥接的数据处理程序。
输入数据是二进制的,我使用 Python 读取数据并将它们传递给 R,然后收集结果以输出。
数据被组织成片段,每个片段大约 100 个字节(每个值 1 个字节 * 100 个值)。
他们现在才工作,但速度非常低。以下是我对 1GB 大小(即 10^7 条)数据的一些测试:
如果我禁用 Rpy2 调用以进行空运行,Python 需要大约 90 分钟才能使用一个单线程在 Intel(R) Xeon(TM) CPU 3.06GHz 上循环。
如果我在 Xeon 双核上启用全部功能和多线程,则(估计)程序需要大约 200 小时才能完成。
我多次杀死Python程序的调用堆栈几乎总是指向Rpy2函数接口。我也做了分析,得到了类似的结果。
所有这些观察表明 Rpy2 调用的 R 部分是瓶颈。所以我分析了我的 R 程序的独立版本,但分析摘要指向“匿名”。我仍在努力查看我的 R 脚本的哪一部分是最耗时的。*****已更新,请参阅下面的编辑 *****
有两个可疑的候选通过,一个是使用来自 cran[1] 的 wmtsa 的连续小波变换(CWT)和小波变换模最大值(WTMM),另一个是前高斯曲线的非线性拟合。
我想到的是:
为了拟合,我可以用内联 C 代码代替 R 路由吗?C和fortran中有许多合适的库......(来自网络的想法;我从来没有这样做过;不确定)
对于小波算法....我将不得不分析 wmtsa 包以重写 C 中的热点?.... 使用 C 或 fortran 重新实现整个 wmtsa 包对我来说非常重要。我没有太多的编程经验。
文件中的数据块以 20 个连续字节组织,我可以直接映射到类似 C 的 char* 数组吗?目前我的 Python 程序一次只读取一个字节并将其附加到一个列表中,这很慢。这部分代码需要 1.5 小时,而 R 需要约 200 小时,所以不是那么紧急。
这是我第一次遇到解决实际问题的程序效率。我对这些信息感到不知所措。请给我一些关于下一步做什么和如何做的建议。
干杯!
脚注:
* 更新 *
感谢 cran 的 proftools,我设法创建了一个调用堆栈图。我可以看到大约 56% 的时间都花在了 wmtsa 上,代码片段如下:
W <- wavCWT(s,wavelet="gaussian1",variance=1/p) # 1/4
W.tree <-wavCWTTree(W) # 1/2
holderSpectrum(W.tree) # 1/4
约 28% 的时间花在 nls 上:
nls(y ~ Q * dexGAUS(x, m, abs(s), abs(n)) + B, start = list(Q = 1000, m = h$time[i], s = 3, n = 8, B = 0), algorithm="default", trace=FALSE)
从 gamlss.dist 包中评估 dexGAUS 需要花费大部分时间。
剩余约 10% 的 R 时间花在数据传递/拆分/聚合/子集上。