gpt4 book ai didi

r - 使用 Rprof 分析 data.table 的 setkey 操作

转载 作者:行者123 更新时间:2023-12-04 10:44:44 31 4
gpt4 key购买 nike

我正在使用一个相对较大的 data.table数据集并尝试分析/优化代码。我正在使用 Rprof ,但我注意到在 setkey 操作中花费的大部分时间未包含在 Rprof 摘要中。有没有办法包括这个花费的时间?

这是一个小测试,用于显示 Rprof 摘要中未表示为数据表设置键所花费的时间:

创建一个测试函数,在数据表上运行分析的 setkey 操作:

    testFun <- function(testTbl) {
Rprof()
setkey(testTbl, x, y, z)
Rprof(NULL)
print(summaryRprof())
}

然后创建一个足够大的测试数据表来感受setkey操作的权重:
    testTbl = data.table(x=sample(1:1e7, 1e7), y=sample(1:1e7,1e7), z=sample(1:1e7,1e7))

然后运行代码,并将其包装在 system.time 操作中以显示 system.time 总时间和 rprof 总时间之间的差异:
>   system.time(testFun(testTbl))
$by.self
self.time self.pct total.time total.pct
"sort.list" 0.88 75.86 0.88 75.86
"<Anonymous>" 0.08 6.90 1.00 86.21
"regularorder1" 0.08 6.90 0.92 79.31
"radixorder1" 0.08 6.90 0.12 10.34
"is.na" 0.02 1.72 0.02 1.72
"structure" 0.02 1.72 0.02 1.72

$by.total
total.time total.pct self.time self.pct
"setkey" 1.16 100.00 0.00 0.00
"setkeyv" 1.16 100.00 0.00 0.00
"system.time" 1.16 100.00 0.00 0.00
"testFun" 1.16 100.00 0.00 0.00
"fastorder" 1.14 98.28 0.00 0.00
"tryCatch" 1.14 98.28 0.00 0.00
"tryCatchList" 1.14 98.28 0.00 0.00
"tryCatchOne" 1.14 98.28 0.00 0.00
"<Anonymous>" 1.00 86.21 0.08 6.90
"regularorder1" 0.92 79.31 0.08 6.90
"sort.list" 0.88 75.86 0.88 75.86
"radixorder1" 0.12 10.34 0.08 6.90
"doTryCatch" 0.12 10.34 0.00 0.00
"is.na" 0.02 1.72 0.02 1.72
"structure" 0.02 1.72 0.02 1.72
"is.unsorted" 0.02 1.72 0.00 0.00
"simpleError" 0.02 1.72 0.00 0.00

$sample.interval
[1] 0.02

$sampling.time
[1] 1.16

user system elapsed
31.112 0.211 31.101

请注意 1.16 和 31.101 的时间差异。

阅读?Rprof,我明白为什么会发生这种差异:

Functions will only be recorded in the profile log if they put a context on the call stack (see sys.calls). Some primitive functions do not do so: specifically those which are of type "special" (see the ‘R Internals’ manual for more details).



那么这就是为什么在 setkey 操作中花费的时间没有在 Rprof 中表示的原因吗?是否有解决方法让 Rprof 监视所有 data.table 的操作(包括 setkey,也许还有其他我没有注意到的操作)?我基本上想让 system.time 和 Rprof 时间匹配。

这是最可能相关的 sessionInfo():
>   sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-apple-darwin10.8.0 (64-bit)

data.table_1.8.11

当 Rprof() 不在函数调用中时,我仍然观察到这个问题:
>   testFun <- function(testTbl) {
+ setkey(testTbl, x, y, z)
+ }

> Rprof()
> system.time(testFun(testTbl))
user system elapsed
28.855 0.191 28.854
> Rprof(NULL)
> summaryRprof()
$by.self
self.time self.pct total.time total.pct
"sort.list" 0.86 71.67 0.88 73.33
"regularorder1" 0.08 6.67 0.92 76.67
"<Anonymous>" 0.06 5.00 0.98 81.67
"radixorder1" 0.06 5.00 0.10 8.33
"gc" 0.06 5.00 0.06 5.00
"proc.time" 0.04 3.33 0.04 3.33
"is.na" 0.02 1.67 0.02 1.67
"sys.function" 0.02 1.67 0.02 1.67

$by.total
total.time total.pct self.time self.pct
"system.time" 1.20 100.00 0.00 0.00
"setkey" 1.10 91.67 0.00 0.00
"setkeyv" 1.10 91.67 0.00 0.00
"testFun" 1.10 91.67 0.00 0.00
"fastorder" 1.08 90.00 0.00 0.00
"tryCatch" 1.08 90.00 0.00 0.00
"tryCatchList" 1.08 90.00 0.00 0.00
"tryCatchOne" 1.08 90.00 0.00 0.00
"<Anonymous>" 0.98 81.67 0.06 5.00
"regularorder1" 0.92 76.67 0.08 6.67
"sort.list" 0.88 73.33 0.86 71.67
"radixorder1" 0.10 8.33 0.06 5.00
"doTryCatch" 0.10 8.33 0.00 0.00
"gc" 0.06 5.00 0.06 5.00
"proc.time" 0.04 3.33 0.04 3.33
"is.na" 0.02 1.67 0.02 1.67
"sys.function" 0.02 1.67 0.02 1.67
"formals" 0.02 1.67 0.00 0.00
"is.unsorted" 0.02 1.67 0.00 0.00
"match.arg" 0.02 1.67 0.00 0.00

$sample.interval
[1] 0.02

$sampling.time
[1] 1.2

EDIT2:我的机器上的 1.8.10 也有同样的问题,只加载了 data.table 包。即使 Rprof() 调用不在函数内,时间也不相等:
> library(data.table)
data.table 1.8.10 For help type: help("data.table")
> base::source("/tmp/r-plugin-claytonstanley/Rsource-86075-preProcess.R", echo=TRUE)

> testFun <- function(testTbl) {
+ setkey(testTbl, x, y, z)
+ }
> testTbl = data.table(x=sample(1:1e7, 1e7), y=sample(1:1e7,1e7), z=sample(1:1e7,1e7))
> Rprof()
> system.time(testFun(testTbl))
user system elapsed
29.516 0.281 29.760
> Rprof(NULL)
> summaryRprof()

EDIT3:即使 setkey 也不起作用不在函数内:
> library(data.table)
data.table 1.8.10 For help type: help("data.table")
> testTbl = data.table(x=sample(1:1e7, 1e7), y=sample(1:1e7,1e7), z=sample(1:1e7,1e7))
> Rprof()
> setkey(testTbl, x, y, z)
> Rprof(NULL)
> summaryRprof()

EDIT4:即使从 --vanilla 调用 R 也不起作用简单的终端提示。

EDIT5:在 Linux VM 上测试时是否有效。但对我来说仍然不适用于达尔文机器。

EDIT6:在看到 Rprof.out 文件被创建后不起作用,所以它不是写访问问题。

EDIT7:从源编译 data.table 并创建新的临时用户并在该帐户上运行后不起作用。

EDIT8:通过 MacPorts 从 darwin 的源代码编译 R 3.0.2 时不起作用。

EDIT9:在不同的 darwin 机器上工作,一台运行相同操作系统版本 (10.6.8) 的 Macbook Pro 笔记本电脑。在运行相同 OS 版本、R 版本、data.table 版本等的 MacPro 台式机上仍然不起作用。

我认为台式机在 64 位内核模式(非默认)下运行是 b/c,而笔记本电脑是 32 位(默认)。确认的。

最佳答案

很好的问题。鉴于编辑,我不确定,无法重现。暂时把剩下的答案留在这里。

我已经在我的(非常慢的)上网本上进行了测试,它运行良好,请参见下面的输出。

我现在可以告诉你为什么setkey在那个测试用例上太慢了。当级别数很大(此处大于 100,000)时,它将恢复为比较排序而不是计数排序。是的,如果您在实践中拥有这样的数据,那就太差了。通常,我们在第一列中有不到 100,000 个唯一值,然后是第二列中的日期。两列都可以使用计数排序进行排序,性能还可以。

这是一个已知问题,我们一直在努力解决。 Arun 已经对范围 > 100,000 的整数实现了基数排序来解决这个问题,这在下一个版本中。 但我们仍在整理 v1.8.11。 请参阅我们在科隆的演讲,其中更详细地介绍了加速的一些概念。

Inroduction to data.table and news from v1.8.11

这是 v1.8.10 的输出,以及 R 版本和 lscpu信息(供您娱乐)。我喜欢在带有小缓存的非常差的机器上进行测试,以便在开发中我可以看到当数据在带有较大缓存的较大机器上扩展时可能会产生什么影响。

$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: AuthenticAMD
CPU family: 20
Model: 2
Stepping: 0
CPU MHz: 800.000
BogoMIPS: 1995.01
Virtualisation: AMD-V
L1d cache: 32K
L1i cache: 32K
L2 cache: 512K
NUMA node0 CPU(s): 0,1

$ R
R version 3.0.2 (2013-09-25) -- "Frisbee Sailing"
Copyright (C) 2013 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

> require(data.table)
Loading required package: data.table
data.table 1.8.10 For help type: help("data.table")
> testTbl = data.table(x=sample(1:1e7, 1e7), y=sample(1:1e7,1e7), z=sample(1:1e7,1e7))
> testTbl
x y z
1: 1748920 6694402 7501082
2: 4571252 565976 5695727
3: 1284455 8282944 7706392
4: 8452994 8765774 6541097
5: 6429283 329475 5271154
---
9999996: 2019750 5956558 1735214
9999997: 1096888 1657401 3519573
9999998: 1310171 9002746 350394
9999999: 5393125 5888350 7657290
10000000: 2210918 7577598 5002307
> Rprof()
> setkey(testTbl, x, y, z)
> Rprof(NULL)
> summaryRprof()
$by.self
self.time self.pct total.time total.pct
"sort.list" 195.44 91.34 195.44 91.34
".Call" 5.38 2.51 5.38 2.51
"<Anonymous>" 4.32 2.02 203.62 95.17
"radixorder1" 4.32 2.02 4.74 2.22
"regularorder1" 4.28 2.00 199.30 93.15
"is.na" 0.12 0.06 0.12 0.06
"any" 0.10 0.05 0.10 0.05

$by.total
total.time total.pct self.time self.pct
"setkey" 213.96 100.00 0.00 0.00
"setkeyv" 213.96 100.00 0.00 0.00
"fastorder" 208.36 97.38 0.00 0.00
"tryCatch" 208.36 97.38 0.00 0.00
"tryCatchList" 208.36 97.38 0.00 0.00
"tryCatchOne" 208.36 97.38 0.00 0.00
"<Anonymous>" 203.62 95.17 4.32 2.02
"regularorder1" 199.30 93.15 4.28 2.00
"sort.list" 195.44 91.34 195.44 91.34
".Call" 5.38 2.51 5.38 2.51
"radixorder1" 4.74 2.22 4.32 2.02
"doTryCatch" 4.74 2.22 0.00 0.00
"is.unsorted" 0.22 0.10 0.00 0.00
"is.na" 0.12 0.06 0.12 0.06
"any" 0.10 0.05 0.10 0.05

$sample.interval
[1] 0.02

$sampling.time
[1] 213.96

>

关于r - 使用 Rprof 分析 data.table 的 setkey 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21268808/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com