【发布时间】:2010-07-14 01:00:41
【问题描述】:
我正在用 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 上,代码 sn-p 是这样的:
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 时间用于数据传递/拆分/聚合/子集。
【问题讨论】:
-
您需要提供更多详细信息,也许是您认为是 R 代码可疑区域的 sn-ps。在这一点上,您的问题有太多可能的解决方案。但有一件事是,你可能不得不接受你正在做的事情需要一段时间。例如,选项 1,即拟合,通常(同样,细节不够)在 R 中进行了高度优化。其他方式不太可能更快。
-
非常感谢约翰。我已经更新了我的帖子。请看一下:P
-
看看你有什么......这只是需要很长时间。如果有地方可以加速你的 R,你可能想看看burns-stat.com/pages/Tutor/R_inferno.pdf
-
约翰,你的意思是没有一点加速空间?我检查了小波函数,它们已经用 C 实现了。顺便说一句,那是一本好书。
-
如果你的 R 调用不是多次调用,并且以独立的方式(在这种情况下你可以考虑一个简单的并行化),你确实剩下: - 研究算法并尝试优化它们(我认为 dexGAUS 占用了 28% 的大部分运行时间有点令人担忧 - 你是从循环内部调用它,不是吗?) - 改变方法