Merge pull request #14 from hobbyistlabs-coder/bolt-perf-discord-string-builder-16389558094904414313
⚡ Bolt: Optimize string building in Discord channel
This commit is contained in:
commit
a04e19bc03
2 changed files with 29 additions and 6 deletions
|
|
@ -1,3 +1,6 @@
|
|||
## 2024-05-24 - Single Pass String Iteration for Token Estimation
|
||||
**Learning:** `utf8.RuneCountInString(msg)` performs a full iteration over the string. If the string needs to be iterated over again (e.g., `for _, r := range msg`) to check specific rune properties, this results in two full passes over the string.
|
||||
**Action:** Always count the total number of runes manually within the existing `for range` loop when a subsequent full iteration of the string is already required. This essentially halves the execution time.
|
||||
**Action:** Always count the total number of runes manually within the existing `for range` loop when a subsequent full iteration of the string is already required. This essentially halves the execution time.
|
||||
## 2024-05-25 - Efficient String Building in Loops
|
||||
**Learning:** In Go, string concatenation (`+=`) in a loop leads to $O(N^2)$ complexity due to immutability. Using `strings.Builder` provides $O(N)$ efficiency. Additionally, `fmt.Fprintf` has overhead due to format string parsing; direct `sb.WriteString` calls are significantly faster.
|
||||
**Action:** Use `strings.Builder` for building strings in loops and prefer direct `WriteString` calls over `fmt.Fprintf` for maximum performance in hot paths.
|
||||
|
|
|
|||
|
|
@ -406,6 +406,8 @@ func (c *DiscordChannel) handleMessage(s *discordgo.Session, m *discordgo.Messag
|
|||
return localPath // fallback
|
||||
}
|
||||
|
||||
var contentBuilder strings.Builder
|
||||
contentBuilder.WriteString(content)
|
||||
for _, attachment := range m.Attachments {
|
||||
isAudio := utils.IsAudioFile(attachment.Filename, attachment.ContentType)
|
||||
|
||||
|
|
@ -413,21 +415,36 @@ func (c *DiscordChannel) handleMessage(s *discordgo.Session, m *discordgo.Messag
|
|||
localPath := c.downloadAttachment(attachment.URL, attachment.Filename)
|
||||
if localPath != "" {
|
||||
mediaPaths = append(mediaPaths, storeMedia(localPath, attachment.Filename))
|
||||
content = appendContent(content, fmt.Sprintf("[audio: %s]", attachment.Filename))
|
||||
if contentBuilder.Len() > 0 {
|
||||
contentBuilder.WriteByte('\n')
|
||||
}
|
||||
contentBuilder.WriteString("[audio: ")
|
||||
contentBuilder.WriteString(attachment.Filename)
|
||||
contentBuilder.WriteByte(']')
|
||||
} else {
|
||||
logger.WarnCF("discord", "Failed to download audio attachment", map[string]any{
|
||||
"url": attachment.URL,
|
||||
"filename": attachment.Filename,
|
||||
})
|
||||
mediaPaths = append(mediaPaths, attachment.URL)
|
||||
content = appendContent(content, fmt.Sprintf("[attachment: %s]", attachment.URL))
|
||||
if contentBuilder.Len() > 0 {
|
||||
contentBuilder.WriteByte('\n')
|
||||
}
|
||||
contentBuilder.WriteString("[attachment: ")
|
||||
contentBuilder.WriteString(attachment.URL)
|
||||
contentBuilder.WriteByte(']')
|
||||
}
|
||||
} else {
|
||||
mediaPaths = append(mediaPaths, attachment.URL)
|
||||
content = appendContent(content, fmt.Sprintf("[attachment: %s]", attachment.URL))
|
||||
if contentBuilder.Len() > 0 {
|
||||
contentBuilder.WriteByte('\n')
|
||||
}
|
||||
contentBuilder.WriteString("[attachment: ")
|
||||
contentBuilder.WriteString(attachment.URL)
|
||||
contentBuilder.WriteByte(']')
|
||||
}
|
||||
}
|
||||
|
||||
content = contentBuilder.String()
|
||||
if content == "" && len(mediaPaths) == 0 {
|
||||
return
|
||||
}
|
||||
|
|
@ -600,7 +617,10 @@ func (c *DiscordChannel) resolveDiscordRefs(s *discordgo.Session, text string, g
|
|||
if msg.Author != nil {
|
||||
author = msg.Author.Username
|
||||
}
|
||||
fmt.Fprintf(&sb, "\n[linked message from %s]: %s", author, msg.Content)
|
||||
sb.WriteString("\n[linked message from ")
|
||||
sb.WriteString(author)
|
||||
sb.WriteString("]: ")
|
||||
sb.WriteString(msg.Content)
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue