z*******h 发帖数: 346 | 1 比如不管是啥一律pass by value. 暴大的matrix也pass by value, 太变态乐吧。这种
情况显然是pass by reference更effecient. |
s*****n 发帖数: 2174 | 2 也不完全是. R在一定程度上是pass by reference/shallow copy的, 从下面这个例子
可以看出来.
> rm(list = ls()); gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 114487 6.2 350000 18.7 350000 18.7
Vcells 122007 1.0 2818617 21.6 3122026 23.9
> a <- matrix(rnorm(1000000), 1000, 1000); gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 114506 6.2 350000 18.7 350000 18.7
Vcells 1122323 8.6 3523602 26.9 3122340 23.9
> b1 <- b2 <- b3 <- b4 <- a; gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 114510 6.2 350000 18.7 350000 18.7
Vcells 1122323 8.6 3523602 26.9 3122340 23.9
> a[2, 1] <- 3; gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 114514 6.2 350000 18.7 350000 18.7
Vcells 2122325 16.2 3523602 26.9 3122340 23.9
很明显, 当你把a赋值给b1,b2,b3,b4的时候, 系统只是生成了b1,b2,b3,b4到a的
pointer, 而没有真正重新deep copy一遍这个矩阵.
只有当改变a的值的时候, 才真正deep copy.
下面这个例子可以看出来函数里面parameter也是pass by reference的
并没有真正把矩阵a复制一遍到函数里面的mat.
> rm(list = ls()); gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 115302 6.2 350000 18.7 350000 18.7
Vcells 122438 1.0 2818961 21.6 3122449 23.9
> myfun <- function (mat) {print(gc()); return(sum(mat))}
> a <- matrix(rnorm(1000000), 1000, 1000); gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 115325 6.2 350000 18.7 350000 18.7
Vcells 1122447 8.6 3523703 26.9 3122449 23.9
> b <- myfun(a); gc();
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 115345 6.2 350000 18.7 350000 18.7
Vcells 1122474 8.6 3523703 26.9 3122449 23.9
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 115327 6.2 350000 18.7 350000 18.7
Vcells 1122448 8.6 3523703 26.9 3122449 23.9 |
l*********s 发帖数: 5409 | 3 Thanks for the information!
【在 s*****n 的大作中提到】 : 也不完全是. R在一定程度上是pass by reference/shallow copy的, 从下面这个例子 : 可以看出来. : > rm(list = ls()); gc() : used (Mb) gc trigger (Mb) max used (Mb) : Ncells 114487 6.2 350000 18.7 350000 18.7 : Vcells 122007 1.0 2818617 21.6 3122026 23.9 : > a <- matrix(rnorm(1000000), 1000, 1000); gc() : used (Mb) gc trigger (Mb) max used (Mb) : Ncells 114506 6.2 350000 18.7 350000 18.7 : Vcells 1122323 8.6 3523602 26.9 3122340 23.9
|
B******5 发帖数: 4676 | 4 哇,牛,这个太有用了~
【在 s*****n 的大作中提到】 : 也不完全是. R在一定程度上是pass by reference/shallow copy的, 从下面这个例子 : 可以看出来. : > rm(list = ls()); gc() : used (Mb) gc trigger (Mb) max used (Mb) : Ncells 114487 6.2 350000 18.7 350000 18.7 : Vcells 122007 1.0 2818617 21.6 3122026 23.9 : > a <- matrix(rnorm(1000000), 1000, 1000); gc() : used (Mb) gc trigger (Mb) max used (Mb) : Ncells 114506 6.2 350000 18.7 350000 18.7 : Vcells 1122323 8.6 3523602 26.9 3122340 23.9
|
z*******h 发帖数: 346 | 5 这样的semantics不叫pass by reference. 你一write to passed in matrix, R 不还
是make a deep copy了吗。要想让R不这么干,只能用global variable. 不elegant呀
不elegant.
【在 s*****n 的大作中提到】 : 也不完全是. R在一定程度上是pass by reference/shallow copy的, 从下面这个例子 : 可以看出来. : > rm(list = ls()); gc() : used (Mb) gc trigger (Mb) max used (Mb) : Ncells 114487 6.2 350000 18.7 350000 18.7 : Vcells 122007 1.0 2818617 21.6 3122026 23.9 : > a <- matrix(rnorm(1000000), 1000, 1000); gc() : used (Mb) gc trigger (Mb) max used (Mb) : Ncells 114506 6.2 350000 18.7 350000 18.7 : Vcells 1122323 8.6 3523602 26.9 3122340 23.9
|
B******5 发帖数: 4676 | 6 这是JAVA类型的pass by reference,你想的是C++的那种。各有利弊罢了
【在 z*******h 的大作中提到】 : 这样的semantics不叫pass by reference. 你一write to passed in matrix, R 不还 : 是make a deep copy了吗。要想让R不这么干,只能用global variable. 不elegant呀 : 不elegant.
|
z*******h 发帖数: 346 | 7 JAVA木有pass by reference, 只有pass by value.
要说编程语言的features, 还是C#要嘛有嘛,pass by value, pass by reference,
lambda expression, functions as first class objects, 真是全啊。
【在 B******5 的大作中提到】 : 这是JAVA类型的pass by reference,你想的是C++的那种。各有利弊罢了
|
l*********s 发帖数: 5409 | 8 what is first class object?
【在 z*******h 的大作中提到】 : JAVA木有pass by reference, 只有pass by value. : 要说编程语言的features, 还是C#要嘛有嘛,pass by value, pass by reference, : lambda expression, functions as first class objects, 真是全啊。
|
l*********s 发帖数: 5409 | 9 Not a big deal. After all, R is a statistical scripting language. Too
complex syntax is beating its purpose.
【在 z*******h 的大作中提到】 : 这样的semantics不叫pass by reference. 你一write to passed in matrix, R 不还 : 是make a deep copy了吗。要想让R不这么干,只能用global variable. 不elegant呀 : 不elegant.
|
B******5 发帖数: 4676 | 10 JAVA的pass by value是通过pass by reference来体现的。。。
anyway,R是没有你说的那种pass by reference的,一个免费的软件,写软件的人也不
都是编译专家,能做到很多事情已经很amazing了
【在 z*******h 的大作中提到】 : JAVA木有pass by reference, 只有pass by value. : 要说编程语言的features, 还是C#要嘛有嘛,pass by value, pass by reference, : lambda expression, functions as first class objects, 真是全啊。
|
|
|
l*********s 发帖数: 5409 | 11 Actually R does have pass by reference.
【在 B******5 的大作中提到】 : JAVA的pass by value是通过pass by reference来体现的。。。 : anyway,R是没有你说的那种pass by reference的,一个免费的软件,写软件的人也不 : 都是编译专家,能做到很多事情已经很amazing了
|
z*******h 发帖数: 346 | 12 其实可以给R加feature同时做到backward compatible. Perl 也是 free的,可是人家
Larry Wall同学就不断给Perl加feature. 感觉R的community还是太松散,没有owner.
【在 B******5 的大作中提到】 : JAVA的pass by value是通过pass by reference来体现的。。。 : anyway,R是没有你说的那种pass by reference的,一个免费的软件,写软件的人也不 : 都是编译专家,能做到很多事情已经很amazing了
|
B******5 发帖数: 4676 | 13 really,像C++那种?
【在 l*********s 的大作中提到】 : Actually R does have pass by reference.
|
B******5 发帖数: 4676 | 14 嗯,就那几个core developer,而且大部分不是CS背景的
.
【在 z*******h 的大作中提到】 : 其实可以给R加feature同时做到backward compatible. Perl 也是 free的,可是人家 : Larry Wall同学就不断给Perl加feature. 感觉R的community还是太松散,没有owner.
|
D******n 发帖数: 2836 | 15 你说的那个好像是指针对scalar
【在 l*********s 的大作中提到】 : Actually R does have pass by reference.
|
D******n 发帖数: 2836 | 16 对,这是我放弃R的最后一根稻草。。。
【在 z*******h 的大作中提到】 : 比如不管是啥一律pass by value. 暴大的matrix也pass by value, 太变态乐吧。这种 : 情况显然是pass by reference更effecient.
|
B******5 发帖数: 4676 | 17 那你用什么?
话说MATLAB的话对于很大的矩阵可以pass by reference?
【在 D******n 的大作中提到】 : 对,这是我放弃R的最后一根稻草。。。
|
l*********s 发帖数: 5409 | 18 Of course not,
http://stackoverflow.com/questions/2603184/r-pass-by-reference
use environment as wrapper
【在 B******5 的大作中提到】 : really,像C++那种?
|
l*********s 发帖数: 5409 | 19 直接上C++,java呗。matlab 能好到哪里去。
【在 B******5 的大作中提到】 : 那你用什么? : 话说MATLAB的话对于很大的矩阵可以pass by reference?
|
B******5 发帖数: 4676 | 20 matrix的运算还是方便很多
【在 l*********s 的大作中提到】 : 直接上C++,java呗。matlab 能好到哪里去。
|
|
|
D******n 发帖数: 2836 | 21 工作中不需要,以前的确是用Matlab,不过也不见得很大。
【在 B******5 的大作中提到】 : 那你用什么? : 话说MATLAB的话对于很大的矩阵可以pass by reference?
|
a***d 发帖数: 336 | 22 niu!
【在 s*****n 的大作中提到】 : 也不完全是. R在一定程度上是pass by reference/shallow copy的, 从下面这个例子 : 可以看出来. : > rm(list = ls()); gc() : used (Mb) gc trigger (Mb) max used (Mb) : Ncells 114487 6.2 350000 18.7 350000 18.7 : Vcells 122007 1.0 2818617 21.6 3122026 23.9 : > a <- matrix(rnorm(1000000), 1000, 1000); gc() : used (Mb) gc trigger (Mb) max used (Mb) : Ncells 114506 6.2 350000 18.7 350000 18.7 : Vcells 1122323 8.6 3523602 26.9 3122340 23.9
|
s*****n 发帖数: 2174 | 23 没错, 所以这就是为什么我说R只是在一定程度上pass by reference。
当你把a赋值给b的时候,的确是生成的指针而不是deep copy。但是当你改变a或者b的
值,这时候系统是只改变一个值(a和b同时更新了), 还是做一个deep copy然后改变值(
a,b之间只有一个更新)这个取决于你的系统的取舍, 各有利弊.
R作为一个统计环境, 需要真正用到pointer的地方很少, 对安全性的考虑远远大于对
performance的考虑, 所以选择要做deep copy的. 要是默认进行shallow copy, 那么引
起的麻烦要远远大于带来的方便.
C++作为一个全功能语言, 着重点不一样而已.
【在 z*******h 的大作中提到】 : 这样的semantics不叫pass by reference. 你一write to passed in matrix, R 不还 : 是make a deep copy了吗。要想让R不这么干,只能用global variable. 不elegant呀 : 不elegant.
|
d*******o 发帖数: 493 | 24 一直有个R问题没弄明白,想请问songkun还有其它大虾一下: 为什么整数的vector
copy-on-change 要弄两个copy?中间过度的哪个copy是干什么的?
> # Floating
> rm(list = ls())
> a <- runif(1:100)
> tracemem(a)
[1] "<0x026028e0>"
> b <- a
> b[1] <- 1
tracemem[0x026028e0 -> 0x02535490]:
>
> # Integer
> rm(list = ls())
> a <- 1:100
> tracemem(a)
[1] "<0x027dafe8>"
> b <- a
> b[1] <- 1
tracemem[0x027dafe8 -> 0x02788728]:
tracemem[0x02788728 -> 0x025b39e0]:
值(
【在 s*****n 的大作中提到】 : 没错, 所以这就是为什么我说R只是在一定程度上pass by reference。 : 当你把a赋值给b的时候,的确是生成的指针而不是deep copy。但是当你改变a或者b的 : 值,这时候系统是只改变一个值(a和b同时更新了), 还是做一个deep copy然后改变值( : a,b之间只有一个更新)这个取决于你的系统的取舍, 各有利弊. : R作为一个统计环境, 需要真正用到pointer的地方很少, 对安全性的考虑远远大于对 : performance的考虑, 所以选择要做deep copy的. 要是默认进行shallow copy, 那么引 : 起的麻烦要远远大于带来的方便. : C++作为一个全功能语言, 着重点不一样而已.
|
s*****n 发帖数: 2174 | 25 在我的机器上试验的结果, 无论是整数还是浮点,
都只有一行显示.
可能是你的机器上一些特殊原因.
【在 d*******o 的大作中提到】 : 一直有个R问题没弄明白,想请问songkun还有其它大虾一下: 为什么整数的vector : copy-on-change 要弄两个copy?中间过度的哪个copy是干什么的? : > # Floating : > rm(list = ls()) : > a <- runif(1:100) : > tracemem(a) : [1] "<0x026028e0>" : > b <- a : > b[1] <- 1 : tracemem[0x026028e0 -> 0x02535490]:
|
d*******o 发帖数: 493 | |
s*****n 发帖数: 2174 | 27 问了一个公司的大牛同事, 终于搞明白怎么回事了.
a <- 1:100 # class(a) is integer
tracemem(a)
b <- a
b[1] <- 1 # 注意1是numeric双精度, 不是integer
出现的两行转换, 第一次是将b复制一次, 第2次是转换成双精度, 然后才赋值.
看下面的例子, 如果直接赋值integer,就没有这个问题.
a <- 1:100
tracemem(a)
b <- a
b[1] <- 1L
有趣的是下面这个例子, 把一个integer赋值进双精度的vector, 只生成一次转换
a <- c(1,2,3) # a是numeric
tracemem(a)
b <- a
b[1] <- 1L # 只生成一次copy.
也就是说, 将numeric scalar赋值进一个integer的向量, R会首先把vector转换成双精
度, 然后再赋值. 但是把integer scalar赋值进一个numeric向量, R会把scalar先转换
成双精度, 然后赋值进去. |
l*********s 发帖数: 5409 | 28 佩服的五体投地
【在 s*****n 的大作中提到】 : 问了一个公司的大牛同事, 终于搞明白怎么回事了. : a <- 1:100 # class(a) is integer : tracemem(a) : b <- a : b[1] <- 1 # 注意1是numeric双精度, 不是integer : 出现的两行转换, 第一次是将b复制一次, 第2次是转换成双精度, 然后才赋值. : 看下面的例子, 如果直接赋值integer,就没有这个问题. : a <- 1:100 : tracemem(a) : b <- a
|
d*******o 发帖数: 493 | 29 kun哥,太谢谢了,解决了我一个困扰多时的难题。 |
s*****n 发帖数: 2174 | 30 我之前也忽略了integer和numeric的问题. 大牛同事一语中的, NB真的不是吹的.
> class(seq(from=1,to=1000))
[1] "integer"
> class(seq(from=1,to=1000,by=1))
[1] "numeric"
> class(seq(from=1L,to=1000L,by=1))
[1] "numeric"
> class(seq(from=1L,to=1000L,by=1L))
[1] "integer" |
|
|
n*****3 发帖数: 1584 | 31 java only pass by value.
and there is only one kind of pass by reference, with pointer/address.
【在 B******5 的大作中提到】 : 这是JAVA类型的pass by reference,你想的是C++的那种。各有利弊罢了
|
n*****3 发帖数: 1584 | 32 it does not sounds about right.
值(
runtime decision? with same syntax? hard to beleive this.
> a=11
> b=a
> a
[1] 11
> b
[1] 11
> a=0
> b
[1] 11
> a
[1] 0
>
值( |
n*****3 发帖数: 1584 | 33 good to know that, thanks!
it is just round down/up, right?
even this, R does differently. -)
【在 l*********s 的大作中提到】 : 佩服的五体投地
|