git.iko.soy/opencode-android
on master help sign in
Reduce allocation churn from token formatting and markdown escaping
commit6a5c9f095f771039334de01d85a4b882a051ebd1 authoriko <mail@iko.soy> dateTue 30 Jun 2026, 19:00 (3 months ago) parent94b6990
2 files changed+21−8
app/src/main/java/soy/iko/opencode/ui/chat/ConversationExport.kt+11−7 app/src/main/java/soy/iko/opencode/ui/chat/MessageBubble.kt+10−1
app/src/main/java/soy/iko/opencode/ui/chat/ConversationExport.kt+11−7
@@ -40,10 +40,14 @@ fun buildConversationMarkdown(messages: List<MessageWithParts>, title: String?):
4040}
4141
4242/** Escape markdown special characters so user/model text doesn't produce malformed markdown. */
43−private fun escapeMarkdown(text: String): String =
44− text.replace("\\", "\\\\")
45− .replace("*", "\\*")
46− .replace("_", "\\_")
47− .replace("#", "\\#")
48− .replace("`", "\\`")
49− .replace(">", "\\>")
43+private fun escapeMarkdown(text: String): String {
44+ if (text.isEmpty()) return text
45+ val sb = StringBuilder(text.length + 16)
46+ for (c in text) {
47+ when (c) {
48+ '\\', '*', '_', '#', '`', '>' -> sb.append('\\')
49+ }
50+ sb.append(c)
51+ }
52+ return sb.toString()
53+}
app/src/main/java/soy/iko/opencode/ui/chat/MessageBubble.kt+10−1
@@ -106,8 +106,17 @@ private fun MessageTimestamp(info: soy.iko.opencode.data.model.MessageInfo) {
106106 }
107107}
108108
109+// NumberFormat.getNumberInstance performs an expensive ICU locale lookup + object
110+// construction on every call. Reuse a thread-local instance so repeated calls (e.g.
111+// when the message list re-seeds after a reconnect and every visible assistant bubble
112+// recomposes at once) don't each pay that cost. Thread-local because NumberFormat is
113+// not thread-safe.
114+private val tokenNumberFormat: ThreadLocal<java.text.NumberFormat> = ThreadLocal.withInitial {
115+ java.text.NumberFormat.getNumberInstance(java.util.Locale.US)
116+}
117+
109118private fun formatTokens(tokens: Tokens, format: String): String {
110− val nf = java.text.DecimalFormat.getNumberInstance(java.util.Locale.US)
119+ val nf = tokenNumberFormat.get()!!
111120 return format.format(nf.format(tokens.input), nf.format(tokens.output))
112121}
113122