gpt4 book ai didi

c# - 如何优化递归函数的 Reactive 实现

转载 作者:行者123 更新时间:2023-11-30 18:22:31 24 4
gpt4 key购买 nike

我尝试使用 Rx 库在 C# 中创建具有动态间隔的自定义响应式(Reactive)计时器。因为我需要在性能和否方面都进行最优化的代码。我最终使用递归方法的行数。代码如下:

  public static IObservable<TOut> GenerateAsync<TResult, TOut>(
Func<Task<TResult>> initialState,
Func<TResult, bool> condition,
Func<TResult, Task<TResult>> iterate,
Func<TResult, TimeSpan> timeSelector,
Func<TResult, TOut> resultSelector,
IScheduler scheduler = null)
{
var s = scheduler ?? Scheduler.Default;

return Observable.Create<TOut>(async obs =>
{
//You have to do your initial time delay here.
var init = await initialState();

//Process the result
obs.OnNext(resultSelector(init));

return s.Schedule(init, timeSelector(init), async (state, recurse) =>
{
//Check if we are done
if (!condition(state))
{
obs.OnCompleted();
return;
}

//Initiate the next request
state = await iterate(state);

//Process the result
obs.OnNext(resultSelector(state));

//Recursively schedule again
recurse(state, timeSelector(state));

});
});
}

这种方法的问题在于,由于它是递归的,因此堆栈增长非常快。我针对计时器使用情况测试了这种方法,它的内存使用量几乎翻了一番。

Link用于测试我用来获取内存使用测试的代码。

如何在不失去其使用能力的情况下优化此功能?

最佳答案

这似乎是任务和 Observable 的混合体 - 仅 Observable 就足以表达。

要回答您的基本问题 - 它是创建一个具有可变时间段的间隔计时器,该时间段在计时器运行时提供。这可以表示为一个 observable,它将 TimeSpan 的 observable 作为输入并返回 ticks 作为输出,很像内置的 Observable.Interval

    static IObservable<long> MutableInterval(IObservable<TimeSpan> period, IScheduler scheduler)
{
return period.Select(timespan => Observable.Interval(timespan, scheduler))
.Switch()
.Scan(0L, (a, _) => a + 1);
}

这是一个周期缓慢下降的测试:

 var slowlyDecreasing =
Observable.Interval(TimeSpan.FromSeconds(1))
.StartWith(0)
.Select(p => TimeSpan.FromMilliseconds(1000 / (p + 1)))
.Do(p => Console.WriteLine("Period changed to {0}", p));

MutableInterval(slowlyDecreasing, Scheduler.Default).Subscribe(Console.WriteLine);

关于c# - 如何优化递归函数的 Reactive 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33878153/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com