Rのdeep copy問題の一部はずいぶん前に解決されていた
ひとりアドベントカレンダー23日目。
いつものようにAdvanced Rを読んでいると、次のような一節があった。
(あ、来月に翻訳が出ます。)
- 作者: Hadley Wickham,石田基広,市川太祐,高柳慎一,福島真太朗
- 出版社/メーカー: 共立出版
- 発売日: 2016/02/10
- メディア: 単行本
- この商品を含むブログ (29件) を見る
Changes to R 3.1.0 have made this use substantially less important because modifying a list no longer makes a deep copy.
え、deep copyしないんだ。と驚き、調べると確かに公式のNewsに以下のような記載があった。
Avoid duplicating the right hand side values in complex assignments when possible. This reduces copying of replacement values in expressions such as Z$a <- a0 and ansi <- tmp: some package code has relied on there being copies.
https://cran.r-project.org/doc/manuals/r-release/NEWS.html
まあこれよりもRevolutionsの紹介記事の方がわかりやすい記述だった。
Reduced memory use (for example, fewer copies made of objects during some assignments). Intriguingly, R now supports a reference counting system which promises to reduce memory use even further. It's not used by default in 3.1.0, but it "may become the default in the future".
http://blog.revolutionanalytics.com/2014/04/r-310-spring-dance-is-released.html
具体的にどういうことかというと以下のSOにわかりやすい例が示されていたので引用する。
http://stackoverflow.com/a/23393859
## R v3.0.3 df <- data.frame(x=1:5, y=6:10) dplyr::changes(df, transform(df, z=11:15)) ## requires dplyr to be available # Changed variables: # old new # x 0x7ff9343fb4d0 0x7ff9326dfba8 # y 0x7ff9343fb488 0x7ff9326dfbf0 # z <added> 0x7ff9326dfc38 # Changed attributes: # old new # names 0x7ff934170c28 0x7ff934308808 # row.names 0x7ff934551b18 0x7ff934308970 # class 0x7ff9346c5278 0x7ff935d1d1f8
おわかりいただけただろうか。
z列を加えただけなのに、x列とy列もコピーされている。
これが3.1.0以前の挙動だった。
しかし3.1.0以降は以下のようにそのようなコピーはない。
## R v3.1.0 df <- data.frame(x=1:5, y=6:10) dplyr::changes(df, transform(df, z=11:15)) ## requires dplyr to be available # Changed variables: # old new # z <added> 0x7f85d328dda8 # Changed attributes: # old new # names 0x7f85d1459548 0x7f85d297bec8 # row.names 0x7f85d2c66cd8 0x7f85d2bfa928 # class 0x7f85d345cab8 0x7f85d2d6afb8
てっきりコピーするもんだとばかり思いこんでいたので驚いた。
Rコアチームもがんばってるんだなあ。