for(i in 1:1000)
是否实际为向量分配了1000个字长的空间,或者它在C中的行为类似for(i=1;i<=1000;++i)
?
为了澄清这个问题,让我展示for(i in seq(1000))DoSomething(i)
首次实施:
在内存中分配长度为1000的空格,将其标记为v
将1,2,3 ......,1000写入该存储区域
为计数器分配长度为1的内存空间,将其标记为c
为i
在长度为1的内存中分配空格设置c = 0
loopstart:从内存中读取v [c],将值写入i
调用DoSomething,以i为参数
设置c = c + 1
如果c <1000,则转到loopstart
第二次实施:
为i
在长度为1的内存中分配空格设置i = 1
loopstart:调用DoSomething,以i为参数
设置i = i + 1
如果i <= 1000则转到loopstart
第二个在空间复杂性方面比第一个效率高得多。我的问题是,哪一个更接近真正的实施?
答案 0 :(得分:1)
我想我现在看到了你的意思,而且新闻很糟糕(根据我的测试)。
考虑以下代码,运行profvis
:
我们创建向量v
,以显示创建向量时的外观,然后清除RAM并运行空for
循环。看看内存的使用情况,R肯定会在内存中创建一个向量。
出于兴趣,我们可以在环中引入while
循环,因为它的行为更像您的第二个实现&#34;:
再次注意相同的测试,但我们现在也有一个while
循环。请注意,while循环的内存分配具有正面和负面属性,这意味着在此过程中分配了和这么多内存。我假设这是因为在每次迭代中重新创建i
的方式(即:复制,然后由副本覆盖原始)。在我看来,while
表现为你的第二次实施&#34;正如预期的那样,for
表现为您的第一次实施&#34;。
请记住这背后的原因。 for
不仅可用于分配序列向量,还可用于迭代任何向量。例如:
words <- c( "hey", "there", "how", "are", "you" )
for( i in words ) {
print( i )
}
# [1] "hey"
# [1] "there"
# [1] "how"
# [1] "are"
# [1] "you"
如果不在某个时刻分配该向量,那将很难实现。