,我做了一些優化,通過從一個工序......性能.Primitive和。內部
> library(microbenchmark)
> microbenchmark(paste0("this","and","that"))
Unit: microseconds
expr min lq mean median uq max neval
paste0("this", "and", "that") 2.026 2.027 3.50933 2.431 2.837 34.038 100
> microbenchmark(.Internal(paste0(list("this","and","that"),NULL)))
Unit: microseconds
expr min lq mean median uq max neval
.Internal(paste0(list("this", "and", "that"), NULL)) 1.216 1.621 2.77596 2.026 2.027 43.764 100
到目前爲止好...
但後來經過我注意到,list
被定義爲
function (...) .Primitive("list")
我試圖進一步 「簡化」
> microbenchmark(.Internal(paste0(.Primitive("list")("this","and","that"),NULL)))
Unit: microseconds
expr min lq mean median uq max neval
.Internal(paste0(.Primitive("list")("this", "and", "that"), NULL)) 3.241 3.242 4.66433 3.647 3.648 80.638 100
和時間增加!
我的猜測是,處理字符串"list"
是問題的根源,而且它的處理方式不同功能list
但如何實際通話中?
免責聲明:我知道這會傷害可讀性而不僅僅是幫助性能。這只是一些非常簡單的功能,不會改變,而且經常使用,即使在這種成本下也需要輕微的性能問題。
編輯迴應喬希·奧布萊恩的評論:
我不知道這是什麼說關於他的想法,但是從微基準產生
library(compiler)
ff <- compile(function(...){.Internal(paste0(.Primitive("list")("this","and","that"),NULL))})
ff2 <- compile(function(...){.Internal(paste0(list("this","and","that"),NULL))})
microbenchmark(eval(ff),eval(ff2),times=10000)
> microbenchmark(eval(ff2),eval(ff),times=10000)
Unit: microseconds
expr min lq mean median uq max neval
eval(ff2) 1.621 2.026 2.356761 2.026 2.431 144.257 10000
eval(ff) 1.621 2.026 2.455913 2.026 2.431 89.148 10000
,看着劇情(只是用plot()
包裝它看看它自己)運行了很多次,看起來那些在統計上相同的性能,儘管看起來像ff2的「最大」值具有更糟糕的最壞情況。不知道該怎麼做,但也許這會幫助某人。所以基本上說,他們編譯爲相同的代碼。這是否意味着他的評論是答案?
難道是由於事實的'基地::名單身()'是字節編譯,而你的最後一個塊需要一個函數調用的評估('.Primitive(「名單」)')通過評估符號「list」來達到同樣的目的?這只是我的猜測,但似乎字節編譯的一個優點是R實際上不需要評估對'.Primitive(「。list」)的調用,以找到每個C代碼的入口點,並且每次使用函數'list' ... –
由於計算機上的一些隨機事件導致等待資源或某個守護進程臨時阻塞RAM,「最大」情況通常是一次性異常值等。 –
@ JoshO'Brien:我不明白你的意見。 'base :: list'是一個基元,被定義爲'function(...).Primitive(「list」)',因此沒有字節編譯的主體。 –