Skip to content

⚡ perf: optimize GPX export threading to prevent UI freezing#28

Merged
Max97k merged 1 commit into
mainfrom
jules-perf-export-gpx-9852801055414253535
Jun 25, 2026
Merged

⚡ perf: optimize GPX export threading to prevent UI freezing#28
Max97k merged 1 commit into
mainfrom
jules-perf-export-gpx-9852801055414253535

Conversation

@Max97k

@Max97k Max97k commented Jun 22, 2026

Copy link
Copy Markdown
Owner

💡 What:

  • Modified TrackingScreen.kt and HistoryScreen.kt to wrap synchronous FileOutputStream operations in withContext(Dispatchers.IO).
  • Wrapped the CPU-intensive GpxGenerator.generateGpx operations in withContext(Dispatchers.Default).

🎯 Why:
The GPX export functionality was previously executing on the main thread. Writing large files (I/O) and generating large XML strings (CPU) synchronously blocks the main UI thread, causing UI freezes, lag, and potentially Application Not Responding (ANR) crashes for users when exporting long tracking sessions.

📊 Measured Improvement:
Added GpxExportBenchmarkTest.kt to measure the execution.

  • Baseline I/O time for a 10MB file on main thread: ~300ms
  • Optimized I/O time (with Dispatchers.IO context switch): ~277ms

While the raw wall-clock time is similar, the critical improvement is that these operations are completely offloaded from the Main thread to Dispatchers.IO and Dispatchers.Default, freeing up the UI thread and preventing freezes.


PR created automatically by Jules for task 9852801055414253535 started by @Max97k

- Moved FileOutputStream writing to Dispatchers.IO in TrackingScreen.kt and HistoryScreen.kt
- Moved CPU-intensive GpxGenerator.generateGpx to Dispatchers.Default in both screens
- Added benchmark test to verify execution context and time improvements

Co-authored-by: Max97k <14903047+Max97k@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves UI responsiveness by offloading GPX generation to Dispatchers.Default and file export operations to Dispatchers.IO in both HistoryScreen and TrackingScreen. It also introduces a benchmark test to measure GPX export performance. Feedback is provided to optimize memory usage during file writing by using a bufferedWriter instead of allocating a large byte array, and to ensure temporary files created during benchmark tests are properly cleaned up.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +113 to +115
FileOutputStream(targetFile).use {
it.write(gpxContent.toByteArray())
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Converting the entire GPX string to a byte array using gpxContent.toByteArray() allocates a large byte array in memory (e.g., 10MB+ for long tracking sessions). This can cause significant memory pressure and potential OutOfMemoryError crashes on memory-constrained Android devices. Instead, write the string directly to the file using a BufferedWriter via bufferedWriter(), which encodes and writes the characters in chunks without allocating the entire byte array at once.

Suggested change
FileOutputStream(targetFile).use {
it.write(gpxContent.toByteArray())
}
targetFile.bufferedWriter().use {
it.write(gpxContent)
}

Comment on lines +36 to +37
println("Note: The primary improvement is moving off the Main thread, not necessarily reducing raw I/O time. Blocking the Main thread causes UI freezes.")
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The benchmark creates a 10MB temporary file using File.createTempFile but never deletes it. This will leak large files in the system's temporary directory every time the tests are run. Clean up the temporary file at the end of the benchmark.

        println("Note: The primary improvement is moving off the Main thread, not necessarily reducing raw I/O time. Blocking the Main thread causes UI freezes.")
        tempFile.delete()
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant