内存空间使用率为(i in 1:1000)

时间:2017-02-24 03:54:45

标签: r for-loop iterator

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

第二个在空间复杂性方面比第一个效率高得多。我的问题是,哪一个更接近真正的实施?

1 个答案:

答案 0 :(得分:1)

我想我现在看到了你的意思,而且新闻很糟糕(根据我的测试)。

考虑以下代码,运行profvis

enter image description here

我们创建向量v,以显示创建向量时的外观,然后清除RAM并运行空for循环。看看内存的使用情况,R肯定会在内存中创建一个向量。

出于兴趣,我们可以在环中引入while循环,因为它的行为更像您的第二个实现&#34;:

enter image description here

再次注意相同的测试,但我们现在也有一个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"

如果不在某个时刻分配该向量,那将很难实现。