Joshua のコメントに従って編集します。以下に示す動作は R-studio に限定されます!!
OPの質問に答えるために、コピーの根本的な理由(@MartinMorganが説明しているように)は、のNAM(2)SEXPオブジェクトによるものですa
。最初のコマンドに が含まれていなかった場合system.time(.)
、型がa <- rep(1, 10^8)
返さNAM(1)
れ、両方の代入でコピーが作成されません。
Rスタジオでの観察:
ただし、別の興味深い観察/相違点を指摘すると、R-studio で実行する場合、(R64/R32 セッションの動作とは) 気付いていない追加の動作の相違点があります。
(R スタジオでの) 違いは、コードの実行方法に起因するようです。つまり、一度にすべてをコピーして貼り付ける場合 (以下に示すように、出力を含む):
system.time(a <- rep(1L, 10^8))
# user system elapsed
# 0.256 0.263 0.526
.Internal(inspect(a))
# @10745d000 13 INTSXP g0c7 [NAM(2)] (len=100000000, tl=0) 1,1,1,1,1,...
system.time(a[222L] <- 111L)
# user system elapsed
# 0.299 0.199 0.498
.Internal(inspect(a))
# @11f1d6000 13 INTSXP g0c7 [NAM(1)] (len=100000000, tl=0) 1,1,1,1,1,...
system.time(a[333L] <- 111L)
# user system elapsed
# 0 0 0
.Internal(inspect(a))
# @11f1d6000 13 INTSXP g1c7 [MARK,NAM(1)] (len=100000000, tl=0) 1,1,1,1,1,...
2 番目の割り当てにはメモリ コピーが含まれておらず、所要時間は 0 秒であることがわかります。ここで、同じコマンド セットをコピー/貼り付け/実行しますが、1 つずつ実行します (次の行を入力する前に、すべての行の後で Enter キーを押します)。結果は次のとおりです。
system.time(a <- rep(1L, 10^8))
# user system elapsed
# 0.256 0.265 0.588
>
.Internal(inspect(a))
# @10745d000 13 INTSXP g0c7 [NAM(2)] (len=100000000, tl=0) 1,1,1,1,1,...
system.time(a[222L] <- 111L)
# user system elapsed
# 0.302 0.204 0.559
.Internal(inspect(a))
# @11f1d6000 13 INTSXP g0c7 [NAM(2)] (len=100000000, tl=0) 1,1,1,1,1,...
system.time(a[333L] <- 111L)
# user system elapsed
# 0.296 0.208 0.504
>
.Internal(inspect(a))
# @10745d000 13 INTSXP g0c7 [NAM(2)] (len=100000000, tl=0) 1,1,1,1,1,...
同じ構文のコピーが作成され、実行時間は 0.5 秒です。
違いを説明するために(@MartinMorganが彼の回答で説明したように):
最初のケースでは、NAM(2) SEXP オブジェクトであるため、割り当て中に複製されます。ただし、これは、すべての行を一度に実行する最初のケースで 1 回だけ発生します。また、2 番目の代入には MARK (unsigned int) があり、これは「オブジェクトを使用中としてマークする」( R-internalsから) ことを示します。
2 番目のケースでは、R-studio ですべての行に対して Enter キーを押すと、これらの割り当てのそれぞれが NAM(2) SEXP オブジェクトを返します。そのため、毎回コピーが作成されています。