当“by=1”时,“seq”需要很长时间

gen*_*ama 4 r

今天我注意到一些奇怪的事情,在某些情况下添加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)

use*_*330 6

您不需要假设幕后发生了什么,您可以运行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改用。

  • 我建议在“r-devel@r-project.org”邮件列表中提出这个问题(但我的建议是“不要”将其称为“本身”的错误,人们对此非常敏感)。 (2认同)