簡體   English   中英

在功能性反應式編程中緩存流

[英]Caching streams in Functional Reactive Programming

我有一個完全使用FRP范例編寫的應用程序,由於我創建流的方式,我認為我遇到了性能問題。 它是用Haxe編寫的,但問題不是特定於語言的。

例如,我有此函數,該函數返回一個流,該流在每次為該特定部分更新配置文件時都進行解析,如下所示:

function getConfigSection(section:String) : Stream<Map<String, String>> {
    return configFileUpdated()
        .then(filterForSectionChanged(section))
        .then(readFile)
        .then(parseYaml);
}

在反應式編程庫中,我正在使用稱為promhx的鏈的每個步驟都應該記住其最后解析的值,但是我認為每次調用此函數時,我都會重新創建流並重新處理每個步驟。 這是我使用它而不是使用庫的方式的問題。

由於在每次需要YAML時都在解析YAML時調用此函數,因此會破壞性能,並且根據性能分析占用了CPU時間的50%以上。

作為修復,我使用存儲為緩存流的實例變量的Map完成了以下操作:

function getConfigSection(section:String) : Stream<Map<String, String>> {
    var cachedStream = this._streamCache.get(section);
    if (cachedStream != null) {
        return cachedStream;
    }

    var stream = configFileUpdated()
        .filter(sectionFilter(section))
        .then(readFile)
        .then(parseYaml);

    this._streamCache.set(section, stream);
    return stream;
}

這可能是解決問題的好方法,但我覺得不合適。 我想知道是否有人能想到一個更干凈的解決方案,它可能使用功能更強大的方法(關閉等),甚至可以像緩存功能一樣添加到流中。

我可以做的另一種方法是先創建流,然后將其存儲在消費者可以訪問的字段中。 我不喜歡這種方法,因為我不想為每個配置節創建一個字段,我喜歡能夠調用具有特定節的函數並返回流。

我喜歡任何可以給我帶來新觀點的想法!

好吧,我認為一個答案是像這樣抽象出緩存:

class Test {
    static function main() {
        var sideeffects = 0;
        var cached = memoize(function (x) return x + sideeffects++);
        cached(1);
        trace(sideeffects);//1
        cached(1);
        trace(sideeffects);//1
        cached(3);
        trace(sideeffects);//2
        cached(3);
        trace(sideeffects);//2
    }
    @:generic static function memoize<In, Out>(f:In->Out):In->Out {
        var m = new Map<In, Out>();
        return
            function (input:In) 
                return switch m[input] {
                    case null: m[input] = f(input);
                    case output: output;
                }
    }
}

您也許可以找到一種更“實用”的實現方式來進行memoize記錄。 但是重要的是,它現在是單獨的東西,您可以隨意使用它。

您可以選擇memoize(parseYaml)以便在文件中的兩個狀態都被解析一次之后,切換它們的狀態實際上變得非常便宜。 您還可以根據最有價值的策略調整備忘錄以管理緩存大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM