今天我注意到一些奇怪的事情,在某些情况下添加by=1功能seq会导致效率低下。
> system.time(seq(from=936144000, to=1135987200))
user system elapsed
0 0 0
> system.time(seq(from=936144000, to=1135987200, by=1))
user system elapsed
4.42 8.39 18.20
Run Code Online (Sandbox Code Playgroud)
乍一看,结果是相同的:
> all.equal(seq(from=936144000, to=1135987200),
+ seq(from=936144000, to=1135987200, by=1))
[1] TRUE
TRUE
Run Code Online (Sandbox Code Playgroud)
区别似乎在于,省略by=1会导致结果为数字,即使是by明确的整数。
> identical(seq(from=936144000, to=1135987200),
+ seq(from=936144000, to=1135987200, by=1))
[1] FALSE
> class(seq(from=936144000, to=1135987200))
[1] "integer"
> class(seq(from=936144000, to=1135987200, by=1L))
[1] "numeric"
Run Code Online (Sandbox Code Playgroud)
此外,直接调用seq.int(假设这是在幕后发生的事情seq)也比不带任何参数的调用花费更长的时间seq:
> system.time(seq.int(from=936144000, to=1135987200, by=1L))
user system elapsed
0.25 1.68 2.81
Run Code Online (Sandbox Code Playgroud)
如何正确指定by以避免效率低下或获得省略的效率by?
> sessionInfo()
R version 4.1.0 (2021-05-18)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19042)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_4.1.0 RUnit_0.4.32 tools_4.1.0 geneorama_1.7.3 data.table_1.14.0
Run Code Online (Sandbox Code Playgroud)
您不需要假设幕后发生了什么,您可以运行debug(seq)并查看有什么不同。这是一个通用函数,它调用seq.default.
事实seq.default证明,如果by缺少参数(以及您的示例中存在的其他一些条件),seq(from, to)则from:to. 这是非常快的,因为它甚至不分配完整的向量:在最新版本的 R 中,它以特殊格式存储,仅具有范围限制。
如果您查看的话,您可以看到的另一件事seq.default是获得此输出的唯一方法是必须missing(by)是TRUE。所以你的问题的答案是你不能指定by获得相同的速度。
@Baraliuh 的建议很好:如果您愿意seq(from, to, by=1),请from:to改用。
| 归档时间: |
|
| 查看次数: |
47 次 |
| 最近记录: |