6

タイム スタンプを収集し、実行時間をメモ付きで生成する基本的なプロファイリング ツールを作成したいと考えています。唯一の問題は、グローバル変数を使用せずにこれを行う方法を理解するのに苦労していることです。私が達成しようとしている機能を実装する「正しい」方法は何ですか? R にこの機能が既に組み込まれている場合、それは素晴らしいことですが、ここで私が実際に理解しようとしているのは、グローバル変数の使用を避け、より堅牢なコードを記述する方法です。

timeStamps = c()
runTimes = list()

appendRunTimes <- function(note) {
  if(length(timeStamps) < 1) {
    timeStamps <<- Sys.time()
  }
  else {
    timeStamps <<- c(timeStamps, Sys.time())
    diff <- timeStamps[length(timeStamps) ] - timeStamps[length(timeStamps) - 1]
    runTimes <<- c(runTimes,  format(diff))
    names(runTimes)[length(runTimes)] <<-  note
  }

}


appendRunTimes('start')
Sys.sleep(4)
appendRunTimes('test')
4

2 に答える 2

8

クロージャーを使用して書き直した例を次に示します。

RTmonitor <- local({
  timeStamps = c()
  runTimes = list()

  list(
    appendRunTimes=function(note) {
      if(length(timeStamps) < 1) {
        timeStamps <<- Sys.time()
      }
      else {
        timeStamps <<- c(timeStamps, Sys.time())
        diff <- timeStamps[length(timeStamps) ] - timeStamps[length(timeStamps) - 1]
        runTimes <<- c(runTimes,  format(diff))
        names(runTimes)[length(runTimes)] <<-  note
      }
    },
    viewRunTimes=function() {
      return(list(timeStamps=timeStamps,runTimes=runTimes))
    })
})


> RTmonitor$appendRunTimes("start")
> RTmonitor$appendRunTimes("test")
> RTmonitor$viewRunTimes()
$timeStamps
[1] "2013-01-04 18:39:12 EST" "2013-01-04 18:39:21 EST"

$runTimes
$runTimes$test
[1] "8.855587 secs"

値がグローバル環境ではなく、クロージャー内に保存されていることを確認してください。

> timeStamps
Error: object 'timeStamps' not found
> runTimes
Error: object 'runTimes' not found
> RTmonitor$timeStamps
NULL
> RTmonitor$runTimes
NULL

クロージャーとグローバルの回避に関する詳細:

于 2013-01-04T23:40:04.603 に答える
4

ReferenceClasses を使用してこれを行うには、次のようにします。

RTmonitor = setRefClass("RTmonitor",
  fields=list(
    timeStamps="POSIXct",
    runTimes = "list"
    ),
  methods=list(
    appendRunTimes=function(note){
      if(length(timeStamps)==0){
        timeStamps <<- Sys.time()
      }else{
        timeStamps <<- c(timeStamps, Sys.time())
        diff <- timeStamps[length(timeStamps) ] - timeStamps[length(timeStamps) - 1]
        runTimes <<- c(runTimes,  format(diff))
        names(runTimes)[length(runTimes)] <<-  note
      }
    }
    )
  )

クラスを定義したら、オブジェクトをインスタンス化して使用します。

> r = RTmonitor$new()
> r$appendRunTimes("start")
> r$appendRunTimes("test")
> r
Reference class object of class "RTmonitor"
Field "timeStamps":
[1] "2013-01-05 14:52:25 GMT" "2013-01-05 14:52:31 GMT"
Field "runTimes":
$test
[1] "5.175815 secs"

クロージャー アプローチに非常に似ていますが、より形式化されています。たとえば、timeStampsフィールドを として定義する必要がありました。POSIXctこの方法で複数のオブジェクトを作成することもできRTmonitor、それらは独立して動作します。これを行うには、クロージャーをラップするクロージャー コンストラクターを作成する必要があります。

于 2013-01-05T17:21:52.930 に答える