假设在进入长时间运行的进程之前,必须执行一些预启动检查.
还假设一旦满足这些检查,您就不需要再次进行检查(可能有许多检查并且执行起来也相对昂贵).
如何在这里避免国家?
更一般地说,在Python中,你可以使用类似于生成器或协同程序的东西来保存这些检查和状态.是否有一个很好的F-sharpy方法摆脱可变的布尔值,以表明跳过每个满意的检查?
let r = new System.Random()
let someCondition1 () =
r.Next() % 523452321 = 0
let someCondition2 () =
r.Next() % 243142321 = 0
let mutable conditionCheck1 = false
let mutable conditionCheck2 = false
let rec conditionChecks () =
match conditionCheck1 with
| true -> ()
| false -> match someCondition1 () with
| false -> conditionChecks ()
| true -> conditionCheck1 <- true // never check again
match conditionCheck2 with
| true -> ()
| false -> match someCondition2 () with
| false -> conditionChecks ()
| true -> conditionCheck2 <- true // never check again
let rec eventLoop () =
eventLoop ()
conditionChecks ()
eventLoop ()
Run Code Online (Sandbox Code Playgroud)
我看到你的conditionChecks函数在每个false值之后都会递归.在我看来,你正在尝试编写以下算法:
在我看来,每个条件检查都是某种async表达式,这将是一个很好的解决方案.该async会继续运行,直到条件为真,然后完成并返回一个true值.然后,您将在列表中收集异步,并同步运行整个asyncs列表.奖励:如果条件是他们的支票可以并行执行,这将节省您的时间.
let r = new System.Random()
let rec someCondition1 () =
async {
// if r.Next() % 523452321 = 0 then
printfn "Checking condition 1"
if r.Next() % 52 = 0 then // So our output is shorter
return true
else
return! someCondition1 ()
}
let rec someCondition2 () =
async {
// if r.Next() % 243142321 = 0 then
printfn "Checking condition 2"
if r.Next() % 24 = 0 then // So our output is shorter
return true
else
return! someCondition2 ()
}
let allConditions = [
someCondition1 ()
someCondition2 ()
]
let rec eventLoop () =
printfn "Event loop runs now"
// eventLoop () // Disabled so our test run will not infiloop
let ready = allConditions |> Async.Parallel |> Async.RunSynchronously
if Array.reduce (&&) ready then
eventLoop()
else
printfn "Some conditions returned false somehow"
Run Code Online (Sandbox Code Playgroud)
当然,为我运行这个产生了不同的结果,但它们通常看起来像这样:
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 2
Checking condition 2
Checking condition 1
Checking condition 2
Checking condition 1
Checking condition 2
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Event loop runs now
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,条件2设法true在第四次尝试时返回并停止 - 而条件1在获得true结果之前需要大约二十五次尝试.但是一旦得到所有结果true,事件循环就会运行.
顺便说一句,我写这个的方式也允许在条件检查中"中止".如果任何条件检查可以确定它永远不会令人满意,它可能会返回false,在这种情况下,事件循环将不会运行.所以:
let condition1CanNeverBeTrue () =
r.Next() % 123456789 = 0
let rec someCondition1 () =
async {
if r.Next() % 523452321 = 0 then
return true
else
if condition1CanNeverBeTrue() then
return false
else
return! someCondition1 ()
}
Run Code Online (Sandbox Code Playgroud)
您可能不需要这个额外的功能,但它可能会派上用场.
此外,如果您不能并行运行条件但它们必须按顺序运行,则将let ready = ...行替换为:
let ready = allConditions |> List.map Async.RunSynchronously
Run Code Online (Sandbox Code Playgroud)
而且,当然,List.reduce而不是Array.reduce在最后使用.
| 归档时间: |
|
| 查看次数: |
146 次 |
| 最近记录: |