goblinfactory / konsole

Home of the simple console library consisting of ProgressBar, Window, Form, Draw & MockConsole (C# console progress bar with support for single or multithreaded progress updates) Window is a 100%-ish console compatible window, supporting all normal console writing to a windowed section of the screen, supporting scrolling and clipping of console output.
719 stars 61 forks source link

Optimize `Refresh` Call Frequency in Long Running Processes #95

Open hamidmayeli opened 3 weeks ago

hamidmayeli commented 3 weeks ago

When running a lightweight process that repeats a large number of times (e.g., 1 million iterations), setting the maximum count to 1 million and calling Next on each iteration significantly slows down the process. This is especially noticeable compared to calling Next once after every 10,000 iterations.

To improve performance, could we implement a built-in mechanism to cache the current percentage of progress? The idea would be to only call Refresh within the Next method when the percentage has actually changed. This optimization would reduce unnecessary updates and potentially improve efficiency for processes with high iteration counts.

goblinfactory commented 3 weeks ago

@hamidmayeli Do you specifically have a need for this update yourself? The reason I ask, is that the typical use case for a progress bar involves code that actually processes something, normally a queue of things, in which case the code is naturally blocked by the processor.

It sounds like you have an architectural problem if you're polling something at high speed. Perhaps consider redesigning what you're doing to use a message based pattern instead and only call update on the progressBar when there has been a status change.

Alternatively write a short factory function that returns you a refresh() method to an instantiated ProgressBar, that wraps a bit of caching.

Try this with ChatGPT

write me a C# factory function that will create an instance of ProgressBar() and return "refresh(int percent)  function" that is a closure around a local int variable, 
- when Refresh(int x), is called the first time it calls Refresh on the instance of ProgressBar and cached the called value
- The second time it's called it checks if the value has changed, if it has it calls Refresh( newValue) and updates cached value, if not changed, does nothing  
hamidmayeli commented 2 weeks ago

Hi @goblinfactory, No I don't have any need. Someone mentioned your library and I had a quick look at it. And I notice that you could improve it with this idea.

goblinfactory commented 2 weeks ago

@hamidmayeli txs for the suggestion, this should be an easy 1 or 2 line code change in the next release, and simple enough worth adding regardless of whether there's a need for it now or not. Just seems logical, txs!