2

21 個のグローバル環境変数があり、それぞれに大量のデータが含まれています。関数内で参照によってこれらの変数にアクセスしたいのですが、それらの名前をパラメーター化したいので、たとえば、SPdata、NEdata、FRdata などがある場合...コピーを作成せずに「国名」(つまり、「SP、NE」、「FR」など)のみ(サイズがそれぞれ300メガを超えるため)Getはコピーを作成するようです(私のサイズでは非効率的です)これを行うことはできますか? 私は現在どこでも取得を使用しているので、

cData <- get(paste(cCode, "data", sep = "")) 

はい、それらすべてをグローバル環境のリストに入れる必要があることはわかっていますが、今では遅すぎて、すべてのコードをリファクタリングしたくありません。私の「取得」がメモリ効率が低下し、ループ内の複数のアクセスが遅くなる可能性があるだけです。たとえば、リスト内にあるかのように各変数にアクセスできますか?

countryData = list(SPdata, NEdata, FRdata..etc) を使用して、countryData[[paste(cCode, "data", sep = "")]] でアクセスする必要がありましたが、今では遅すぎます。

以下のさまざまなアドレスからわかるように、関数内のいくつかの値を変更するつもりであり、get() は変更時にコピーすることを追加する必要がありました。

> .Internal(inspect(a))
@101b7bcf8 14 REALSXP g0c1 [NAM(2)] (len=1, tl=0) 1
> g <- function() {x <- get("a"); x; x <- 2; .Internal(inspect(x))}
> g()
@101cea648 14 REALSXP g0c1 [NAM(2)] (len=1, tl=0) 2
> 
4

2 に答える 2

6

getコピーを生成しません。たとえば、以下のコードでは、同じアドレス、つまり at にあるため 、 のコピーでxないことがわかります。a.10x00000000077a0010

> a.1 <- 1:1000000
> .Internal(inspect(a.1))
@0x00000000077a0010 13 INTSXP g0c7 [NAM(1)] (len=1000000, tl=0) 1,2,3,4,5,...
> g <- function() { x <- get("a.1"); .Internal(inspect(x)); max(x) }
> g()
@0x00000000077a0010 13 INTSXP g0c7 [NAM(2)] (len=1000000, tl=0) 1,2,3,4,5,...
[1] 1000000

変数を変更すると (追加は変更の一種です)、コピーされます。ここでx開始されまし0x00000000075b95d8たが、変更された後、にコピーされ0x000000000744d8e0、追加された後、今度は再びコピーされました0x000000000754c5e8:

> n <- 10000
> x <- 1:n
> .Internal(inspect(x))
@0x00000000075b95d8 13 INTSXP g0c7 [NAM(1)] (len=10000, tl=0) 1,2,3,4,5,...
> f <- function() {
+ .GlobalEnv$x[[n]] <- 0
+ .Internal(inspect(x))
+ x <<- c(x, 0)
+ .Internal(inspect(x))
+ }
> f()
@0x000000000744d8e0 14 REALSXP g0c7 [NAM(1)] (len=10000, tl=0) 1,2,3,4,5,...
@0x000000000754c5e8 14 REALSXP g0c7 [NAM(1)] (len=10001, tl=0) 1,2,3,4,5,...

上記では、関数内からグローバル変数を変更しましたが、関数外で行ったとしても、コピーされてしまいます。

于 2013-03-30T03:02:47.273 に答える
4

簡単なもの:

  • R セマンティクスは「書き込み時にコピー」であるため、これらの変数の内容を変更しない場合、コピーは作成されません。

  • Rにはメモリプロファイリングがありますが、実際にコピーが作成されていると確信していますか? メモリ プロファイリングの基本については、「R 拡張機能の記述」を参照してください。

  • これらがコピーされていることが本当に確実な場合は、XPtr オブジェクトを使用するか、bigmemory などの外部ポインターを展開するラッパーを使用して、外部ポインターの使用を強制することでこれを防ぐことができます。

于 2013-03-30T02:45:56.140 に答える