I'm modifying a legacy application that can export data to a file. Currently, this process is really slow, but indirectly gives a visual feedback of the progress (it updates the UI from inside a for loop). Simply commenting out the UI code in the loop speeds up the process by an order of magnitude. It's nice, but it's still slow (seconds instead of minutes for a 300kb file). The users do not want the UI to change, nor want any additional dialog windows, but want the application to be faster. This leaves me with 3 options:
Which one should I pursue for the best User experience?
It sounds to me that, if possible, multi-threading may be a fourth and best-of-both-worlds option. You could monitor the progress of the export and update the UI using a separate thread, which should result in a significant boost in export performance.
If this is not an option, is too difficult, or does not help for whatever reason, talking the users into living without the performance-killing UI beast would be the way to go. As far as I'm concerned, waiting a fraction of the time without being told how long it will take is a better experience than waiting a long time even if I know how long I'll be waiting.
If none of these are going to work, my recommendation would be something like your second listed option, updating the UI less often for the sake of performance. It's a decent compromise that should make you happy with the result and the users happy with the noticeable performance boost without totally losing the comfort of their progress bar.
Get a user to wait for a three minute coffee break is nice, but management doesn't like it. You need to make this as fast as you can (async maybe?) and play a little tune to the user while waiting. It's not OK to transform a document of 300 kb in 15 seconds - but if that is your absolute best, you need to entertain your user during the 15 seconds.
How? A progress bar showing actual progress, some quick tip to learn more from or whatever is framed within your 15 s timeframe.
Assuming the process is initiated by a user, then ideally:
It would be very poor UX to have no response for 15 seconds. 15 seconds of no response will feel like an eternity to end-users. They may think to kill the app during that time.
It is much better if users have to wait 1 minute but have a nice feedback along the way. The amount of time will actually feel shorter and users will feel much less frustrated at the end, because they were empowered during the process.
The real question I think you should be asking is why is the performance so slow when updating the UI?
*SOURCE: Designing with the Mind in Mind by Jeff Johnson - Chapter 12 - "We Have Time Requirements"
You don't need to actually update UI to show that the app is working.
You could modify your second alternative (update UI every X seconds) by getting actual data from the process every X seconds, but display progress - or at least some moving sign of activity, like a spinner - continually.
If the progress is more or less constant, you can even interpolate/extrapolate the progress to display it acurately without even needing to measure it in the first place.