R 仿真中规则的快速处理
如果在离散事件模拟中只有几个规则,这并不重要,但如果有很多规则,它们可能相互干扰,您可能希望跟踪使用它们的“哪个”和“哪里”R 仿真中规则的快速处理,r,rete,R,Rete,如果在离散事件模拟中只有几个规则,这并不重要,但如果有很多规则,它们可能相互干扰,您可能希望跟踪使用它们的“哪个”和“哪里” 有人知道如何以与原始函数一样快的速度获得下面的代码吗 是否有比eval(parse(…)更好的选项 下面是一个简单的示例,它显示我在速度中失去了一个因子100。假设您运行一个模拟,其中一个(许多规则)是:选择时间小于5的状态: > a <- rnorm(100, 50, 10) > print(summary(microbenchmark::micr
- 有人知道如何以与原始函数一样快的速度获得下面的代码吗
- 是否有比eval(parse(…)更好的选项
> a <- rnorm(100, 50, 10)
> print(summary(microbenchmark::microbenchmark(a[a < 5], times = 1000L, unit = "us")))
expr min lq mean median uq max neval
a[a < 5] 0.76 1.14 1.266745 1.141 1.52 11.404 1000
myfun <- function(a0) {
return(eval(parse(text = myrule)))
}
> myrule <- "a < a0" # The rule could be read from a file.
print(summary(microbenchmark::microbenchmark(a[myfun(5)], times = 1000L, unit = "us")))
expr min lq mean median uq max neval
a[myfun(5)] 137.61 140.271 145.6047 141.411 142.932 343.644 1000
>打印(摘要(microbenchmark::microbenchmark(a[a<5],times=1000L,unit=“us”))
expr最小lq平均uq最大neval
a[a<5]0.761.1411.2667451.1411.5211.4041000
myfun myrule让我们来分析一下:
Rprof()
for (i in 1:1e4) a[myfun(5)]
Rprof(NULL)
summaryRprof()
#$by.self
# self.time self.pct total.time total.pct
#"parse" 0.36 69.23 0.48 92.31
#"structure" 0.04 7.69 0.06 11.54
#"myfun" 0.02 3.85 0.52 100.00
#"eval" 0.02 3.85 0.50 96.15
#"stopifnot" 0.02 3.85 0.06 11.54
#"%in%" 0.02 3.85 0.02 3.85
#"anyNA" 0.02 3.85 0.02 3.85
#"sys.parent" 0.02 3.85 0.02 3.85
#
#$by.total
# total.time total.pct self.time self.pct
#"myfun" 0.52 100.00 0.02 3.85
#"eval" 0.50 96.15 0.02 3.85
#"parse" 0.48 92.31 0.36 69.23
#"srcfilecopy" 0.12 23.08 0.00 0.00
#"structure" 0.06 11.54 0.04 7.69
#"stopifnot" 0.06 11.54 0.02 3.85
#".POSIXct" 0.06 11.54 0.00 0.00
#"Sys.time" 0.06 11.54 0.00 0.00
#"%in%" 0.02 3.85 0.02 3.85
#"anyNA" 0.02 3.85 0.02 3.85
#"sys.parent" 0.02 3.85 0.02 3.85
#"match.call" 0.02 3.85 0.00 0.00
#"sys.function" 0.02 3.85 0.00 0.00
大部分时间都花在分析上。我们可以通过一个基准来确认这一点:
microbenchmark(a[myfun(5)], times = 1000L, unit = "us")
#Unit: microseconds
# expr min lq mean median uq max neval
# a[myfun(5)] 67.347 69.141 72.12806 69.909 70.933 160.303 1000
a0 <- 5
microbenchmark(parse(text = myrule), times = 1000L, unit = "us")
#Unit: microseconds
# expr min lq mean median uq max neval
# parse(text = myrule) 62.483 64.275 64.99432 64.787 65.299 132.903 1000
为方便起见,您可以将该表达式列表作为S3对象,并为其创建一个漂亮的打印方法,以便获得更好的概述。我理解。您有没有想法,如何以不同的方式跟踪“which”和“where”——而不是像上面所说的那样使用文件?我不理解跟踪“which”和“where”“在哪里"以另一种方式
。您的问题描述似乎缺少关键部分。您的规则是否以文本文件以外的其他形式存在?我运行离散事件模拟。目前,规则作为if-else
语句散布在整个代码中。我们添加的规则越多,规则之间可能发生的冲突就越多,并且ole簿记变得越来越复杂(甚至是一些简单的问题,比如:几个月前我们没有实施类似的规则吗?在哪里?…),所以我认为一定有一种聪明的方法(这不是额外的文档;-)为了解决这个问题。上述方法将以速度为代价解决这些问题,但不幸的是,这不是一个选项。对不起,我对R很陌生,从来没有听说过:你是说saveRDS(myrule1,file=“myrule1.rds”)
,res我是说打印列表(myrule1,myrule2)
表格形式更好。有关R中OOP的说明,请参阅:
myrule1 <- quote(a < a0)
myfun1 <- function(rule, a, a0) {eval(rule)}
microbenchmark(a[myfun1(myrule1, a, 30)], times = 1000L, unit = "us")
#Unit: microseconds
# expr min lq mean median uq max neval
# a[myfun1(myrule1, a, 30)] 1.792 2.049 2.286815 2.304 2.305 30.217 1000