2

我正在用 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),另一个是前高斯曲线的非线性拟合。

我想到的是:

  1. 为了拟合,我可以用内联 C 代码代替 R 路由吗?C和fortran中有许多合适的库......(来自网络的想法;我从来没有这样做过;不确定)

  2. 对于小波算法....我将不得不分析 wmtsa 包以重写 C 中的热点?.... 使用 C 或 fortran 重新实现整个 wmtsa 包对我来说非常重要。我没有太多的编程经验。

  3. 文件中的数据块以 20 个连续字节组织,我可以直接映射到类似 C 的 char* 数组吗?目前我的 Python 程序一次只读取一个字节并将其附加到一个列表中,这很慢。这部分代码需要 1.5 小时,而 R 需要约 200 小时,所以不是那么紧急。

这是我第一次遇到解决实际问题的程序效率。我对这些信息感到不知所措。请给我一些关于下一步做什么和如何做的建议。

干杯!

脚注:

  1. http://cran.r-project.org/web/packages/wmtsa/index.html

* 更新 *

感谢 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 时间花在数据传递/拆分/聚合/子集上。

4

2 回答 2

1

我的理解是你有:

  • 在某些地方使用 rpy2 的 python 代码

  • 可以追溯到对 rpy2 的调用的性能问题

  • 性能问题目前似乎与 rpy2 本身没有太大关系,因为底层 R 主要负责运行时间

  • 您的 R 代码的一部分是一次读取一个字节并将它们附加到一个列表中,您通过将该部分移到 Python 来改进

在没有看到实际代码的情况下尝试提供帮助有点困难,您可能需要考虑:

  • 用于读取字节的缓冲策略(正如 John 已经回答的那样)。

  • 致力于优化你的 R 代码

  • 考虑微不足道的并行化(并最终在云上租用计算空间)

于 2010-07-14T05:25:45.210 回答
1

对于选项 3.. 有效地获取您的数据...在 python 中将其全部读取为一个 long str 类型,只需从文件中读取一次。假设它被称为 myStr。

import array
myNums = array.array('B', myStr)

现在 myNums 是一个易于转换的每个字节的数组...请参阅 help(array.array)... 实际上,看起来您可以通过数组直接从文件中获取它。

这应该可以省去 1.4 小时的数据读取时间。

于 2010-07-14T03:54:30.390 回答