Only rerun the function without rerunning the whole script

Hi, I have a function that runs some heavy computation to produce an image,
and i want to display the image with a slider to adjust the brightness.
like this :

def AdjustBrightness(image, plotpath):
    ## -- Brightness adjustments --
    ShiftBy = st.slider('Brightness adjustments')
    ## -- Save image --
    plt.figure(); 
    librosa.display.specshow(image + float(ShiftBy))
    plt.savefig(plotpath)
    ## -- Display image --
    image = Image.open(plotpath)
    st.image(image, caption='Spectrogram & Onset', use_column_width=True)

plotpath = "plot.png"

image = SomeHeavyComputation()

AdjustBrightness(image, plotpath)

However everytime i adjust the slider, the SomeHeavyComputation() is re-ran, which takes up alot of time.
How do i prevent the earlier computations, and only re-run AdjustBrightness() when i adjust the slider?

Hi @divinekage -

This is the basis for the caching functionality of Streamlit:

Yea I get that. So what I have is that I am displaying 5 pictures. And when I display the 6th picture, which is this to adjust brightness, it will rerun the whole script. And each picture takes 0.5 seconds to load.
So when I change the slider, it’ll take 2.5s to load the past 5 pictures, then follow by another 0.5s for this 6th picture.
Main bottleneck is in the I/O operations (writing reading from file).
So I only want to re-run the 6th picture operation, without rerunning the previous 5 pictures.

By caching the load of each picture, you take out the I/O portion, because the cache will read from RAM. Thus 0.5s will become way shorter, hopefully imperceptible.

The caching only makes it such that you return values without actually running the function right.
Which means if I do something like

@st.cache()
def AdjustBrightness(image, plotpath):
    ...
    return None

when I run AdjustBrightness(image, plotpath) for the first time it will plot the image and return None
When I run it for the 2nd time. It will not run whats inside. And return None immediately, which is not what I want because the plot will then disappear

Cache the loading of the picture from disk. You can cache the brightness as well, but if you cache the loading of the picture it will remove the disk IO

If I understand you correctly, i should be getting the binary values from plotpath from cache.
I adjusted my function like this:

@st.cache(suppress_st_warning=True)
def AdjustBrightness(image, plotpath):
    ## -- Brightness adjustments --
    ShiftBy = st.slider('Brightness adjustments')
    ## -- Save image --
    plt.figure(); 
    librosa.display.specshow(image + float(ShiftBy))
    plt.savefig(plotpath)
    ## -- Display image --
    return Image.open(plotpath)

plotpath = "plot.png"
image = SomeHeavyComputation()

AdjustBrightness(image, plotpath) # This runs in 0.00915s, fast because from cache
st.image(image, caption='Spectrogram & Onset', use_column_width=True) # 0.500s

However the bottleneck is still in the st.image() function, which is 0.5s

1 Like