Reactive.jl graph / tree grows very large

reactiveprogramming

#1

Hey,

I’m using Reactive.jl to do some signal processing / simulation. I start off with a simple tick𝑆 = Signal(0). Each tick then generates a 1ms signal array containing multiple subsignals:

signal𝑆s = map(1:11) do id
    φₙ𝑆 = foldp((prev_phase, _) -> 2 * π * f / f_s * 1000, φ₀, tick𝑆)
    carrier𝑆 = map(φₙ -> exp(1im * (2 * π * f / f_s * 1:1000 + φₙ)), previous(φₙ𝑆))
    subcarrier𝑆 = # ...
    map((carrier, subcarrier) -> carrier .* subcarrier, carrier𝑆, subcarrier𝑆)
end
signal𝑆 = map(+, signal𝑆s...)

This signal is buffered / filtered / transformed etc.
Here is a buffer and filter example:

function takelast(n::Int, signal𝑆::Reactive.Signal)
    if n > 1
        [takelast(n - 1, previous(signal𝑆)); signal𝑆]
    else
        [signal𝑆]
    end
end

function buffer(n::Int, signal𝑆::Reactive.Signal)
    every_nth𝑆 = filter(cnt -> cnt % n == 0, 0, foldp((cnt, _) -> cnt + 1, 0, signal𝑆))
    lasts = takelast(n, signal𝑆)
    lasts_concatinated = map(hcat, lasts...)
    return sampleon(every_nth𝑆, lasts_concatinated)
end

filter𝑆 = map(signal -> some_filter_fun(signal), buffer(10, signal𝑆))
filtered_signal𝑆 = map((signal, some_filter) -> some_filter * signal, signal𝑆, filter𝑆)

There are multiples of those buffers / filters in my code.
In the end reactive graph grows very large (several megabytes) and my computer is not able to handle the memory needed anymore.
Here is an extraction (only a small part!):

143: "map(filterwhen(map(input-2), filterwhen(map(filter(foldp(map(map(input), map(map(map(previous(foldp(input))), map(previous(foldp(input)-2)))), map(map(map(previous(foldp(input)-3)), map(previous(foldp(input)-4)))), map(map(map(previous(foldp(input)-5)), map(previous(foldp(input)-6)))), map(map(map(previous(foldp(input)-7)), map(previous(foldp(input)-8)))), map(map(map(previous(foldp(input)-9)), map(previous(foldp(input)-10)))), map(map(map(previous(foldp(input)-11)), map(previous(foldp(input)-12)))), map(map(map(previous(foldp(input)-13)), map(previous(foldp(input)-14)))), map(map(map(previous(foldp(input)-15)), map(previous(foldp(input)-16)))), map(map(map(previous(foldp(input)-17)), map(previous(foldp(input)-18)))), map(map(map(previous(foldp(input)-19)), map(previous(foldp(input)-20)))), map(map(map(previous(foldp(input)-21)), map(previous(foldp(input)-22)))))))), sampleon(map(previous(previous(previous(map(map(map(map(input), map(map(map(previous(foldp(input))), map(previous(foldp(input)-2)))), map(map(map(previous(foldp(input)-3)), map(previous(foldp(input)-4)))), map(map(map(previous(foldp(input)-5)), map(previous(foldp(input)-6)))), map(map(map(previous(foldp(input)-7)), map(previous(foldp(input)-8)))), map(map(map(previous(foldp(input)-9)), map(previous(foldp(input)-10)))), map(map(map(previous(foldp(input)-11)), map(previous(foldp(input)-12)))), map(map(map(previous(foldp(input)-13)), map(previous(foldp(input)-14)))), map(map(map(previous(foldp(input)-15)), map(previous(foldp(input)-16)))), map(map(map(previous(foldp(input)-17)), map(previous(foldp(input)-18)))), map(map(map(previous(foldp(input)-19)), map(previous(foldp(input)-20)))), map(map(map(previous(foldp(input)-21)), map(previous(foldp(input)-22))))), map(sampleon(map(previous(map(map(input), map(map(map(previous(foldp(input))), map(previous(foldp(input)-2)))), map(map(map(previous(foldp(input)-3)), map(previous(foldp(input)-4)))), map(map(map(previous(foldp(input)-5)), map(previous(foldp(input)-6)))), map(map(map(previous(foldp(input)-7)), map(previous(foldp(input)-8)))), map(map(map(previous(foldp(input)-9)), map(previous(foldp(input)-10)))), map(map(map(previous(foldp(input)-11)), map(previous(foldp(input)-12)))), map(map(map(previous(foldp(input)-13)), map(previous(foldp(input)-14)))), map(map(map(previous(foldp(input)-15)), map(previous(foldp(input)-16)))), map(map(map(previous(foldp(input)-17)), map(previous(foldp(input)-18)))), map(map(map(previous(foldp(input)-19)), map(previous(foldp(input)-20)))), map(map(map(previous(foldp(input)-21)), map(previous(foldp(input)-22)))))), # .............

Is there anything I can do about it? At the moment everything is based on a simple tick at the beginning. I guess I could break that graph down, if I create new intermediate Signals like so yield(); im_signal𝑆 = Signal(value(prev_signal𝑆)).