Skip to content

perf: reduce screenshot encoding time and XML parsing overhead#2

Open
sanjarcode wants to merge 3 commits into
masterfrom
claude/issue-1-20260404-1135
Open

perf: reduce screenshot encoding time and XML parsing overhead#2
sanjarcode wants to merge 3 commits into
masterfrom
claude/issue-1-20260404-1135

Conversation

@sanjarcode
Copy link
Copy Markdown
Owner

Fixes performance issues reported in #1

  • Scale screenshots to 0.5x before annotation/encoding (configurable via SCREENSHOT_SCALE env var)
  • Set PNG compress_level=1 for 3-5x faster encoding
  • Pre-compile bounds regex in tree/utils.py
  • Move threading import to module level
  • Remove asyncio.sleep(1) from lifespan

Generated with Claude Code

#1

- Scale down screenshots to 0.5x (configurable via SCREENSHOT_SCALE env)
  before annotation and encoding, cutting pixel count by 75%
- Set PNG compress_level=1 in screenshot_in_bytes and as_base64 for
  3-5x faster encoding with slightly larger output
- Pre-compile bounds regex in tree/utils.py to avoid recompilation
  on every node during XML tree parsing
- Move threading import to module level in mobile/service.py
- Remove asyncio.sleep(1) from lifespan to eliminate startup delay

Co-authored-by: Sanjar Afaq <sanjarcode@users.noreply.github.com>
@sanjarcode
Copy link
Copy Markdown
Owner Author

@claude, can you add some testing instrumentations, at general points (that are also in the master branch). So i can assess performancer changes. Ensure the logs are put into $branch-name.log, and they are git ignored, so I can see them without interference.

@claude
Copy link
Copy Markdown

claude Bot commented Apr 4, 2026

Claude finished @sanjarcode's task in 3m 16s —— View job


Performance Instrumentation Added

  • Gather context and read relevant files
  • Identify instrumentation points in master branch code
  • Create perf_log.py timing utility (writes to {branch-name}.log)
  • Instrument mobile/service.py: capture_data, get_state, encoding methods
  • Instrument tree/service.py: get_element_tree, get_interactive_elements, annotated_screenshot
  • Update .gitignore to ignore *.log
  • Commit and push changes

What was added

New file: src/android_mcp/perf_log.py
A lightweight timing utility. On import it runs git rev-parse --abbrev-ref HEAD to get the branch name (with / replaced by -) and writes all timings to {branch-name}.log in the working directory.

Instrumented points (all present in master branch code paths):

Label Where
capture_data.dump_hierarchy XML dump from device
capture_data.screenshot Screenshot capture from device
capture_data.total_parallel Total wall time waiting for both threads
get_state.capture_data Full capture phase
get_state.tree_state XML parse + element filtering
get_state.screenshot_resize PIL resize() call
get_state.annotated_screenshot Annotation draw phase
get_state.quantize Optional quantization
get_element_tree.fromstring ElementTree.fromstring() parse
get_interactive_elements.findall XPath findall on the tree
get_interactive_elements.filter_loop Iterating + filtering nodes
annotated_screenshot.draw_all Drawing all bounding boxes
screenshot_in_bytes.png_save PNG encoding to bytes
as_base64.png_save PNG encoding to base64

Sample log output (claude-issue-1-20260404-1135.log):

--- get_state use_vision=True [14:32:01.123] ---
  capture_data.dump_hierarchy: 312.4ms
  capture_data.screenshot: 287.1ms
  capture_data.total_parallel: 315.2ms
  get_state.capture_data: 316.0ms
  get_element_tree.fromstring: 18.3ms
  get_interactive_elements.findall: 4.1ms
  get_interactive_elements.filter_loop: 12.7ms
  get_state.tree_state: 35.8ms
  get_state.screenshot_resize: 22.1ms
  annotated_screenshot.draw_all: 41.5ms
  get_state.annotated_screenshot: 42.0ms
  screenshot_in_bytes.png_save: 68.3ms

Run the server from the project root and the log file will appear there automatically. Since *.log is now in .gitignore, it won't be tracked by git.
|

github-actions Bot and others added 2 commits April 4, 2026 12:24
- Add perf_log.py with timed() context manager writing to {branch-name}.log
- Instrument capture_data: dump_hierarchy, screenshot, total parallel time
- Instrument get_state: capture, tree parsing, resize, annotation, encoding
- Instrument get_element_tree, get_interactive_elements, annotated_screenshot
- Add *.log to .gitignore so log files are not tracked

Co-authored-by: Sanjar Afaq <sanjarcode@users.noreply.github.com>
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