Optimize inferMediaType by avoiding strings.ToLower allocation
- Moves strings.ToLower to after the empty extension check - Adds fast paths for well-formed content types to bypass ToLower entirely Co-authored-by: hobbyistlabs-coder <267281733+hobbyistlabs-coder@users.noreply.github.com>
This commit is contained in:
parent
8b9a4fce62
commit
cfc622d848
2 changed files with 33 additions and 14 deletions
|
|
@ -8,3 +8,6 @@
|
||||||
## 2024-05-26 - Avoid Unnecessary `strings.ToLower`
|
## 2024-05-26 - Avoid Unnecessary `strings.ToLower`
|
||||||
**Learning:** Calling `strings.ToLower` on the entire message content allocates a new string and iterates over all runes. This causes measurable GC pressure and latency on hot paths like feature extraction during routing.
|
**Learning:** Calling `strings.ToLower` on the entire message content allocates a new string and iterates over all runes. This causes measurable GC pressure and latency on hot paths like feature extraction during routing.
|
||||||
**Action:** Use fast paths to bypass `strings.ToLower`. For instance, check if a requisite character (like a dot `.`) exists, or check common casings directly (`DATA:IMAGE` vs `data:image`) before falling back to full case-normalization.
|
**Action:** Use fast paths to bypass `strings.ToLower`. For instance, check if a requisite character (like a dot `.`) exists, or check common casings directly (`DATA:IMAGE` vs `data:image`) before falling back to full case-normalization.
|
||||||
|
## 2025-03-20 - String Operations Fast Paths and Avoiding Double Searches
|
||||||
|
**Learning:** When trying to optimize `strings.ToLower`, ensure you don't introduce regressions with byte-to-rune casting on UTF-8 strings. Also, `strings.Contains(s, sub)` literally calls `strings.Index(s, sub)` under the hood. Using `strings.Contains` followed immediately by `strings.Index` to extract the position is an anti-pattern that searches the string twice, undermining the intended performance optimization.
|
||||||
|
**Action:** Always prefer a single `strings.Index` call over `Contains`+`Index`. Stick to one single optimization per PR to reduce risk and review burden.
|
||||||
|
|
|
||||||
|
|
@ -102,28 +102,44 @@ func formatToolsForLog(toolDefs []providers.ToolDefinition) string {
|
||||||
// inferMediaType determines the media type ("image", "audio", "video", "file")
|
// inferMediaType determines the media type ("image", "audio", "video", "file")
|
||||||
// from a filename and MIME content type.
|
// from a filename and MIME content type.
|
||||||
func inferMediaType(filename, contentType string) string {
|
func inferMediaType(filename, contentType string) string {
|
||||||
ct := strings.ToLower(contentType)
|
// Fast path for common, correctly cased content types
|
||||||
fn := strings.ToLower(filename)
|
if strings.HasPrefix(contentType, "image/") {
|
||||||
|
|
||||||
if strings.HasPrefix(ct, "image/") {
|
|
||||||
return "image"
|
return "image"
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(ct, "audio/") || ct == "application/ogg" {
|
if strings.HasPrefix(contentType, "audio/") || contentType == "application/ogg" {
|
||||||
return "audio"
|
return "audio"
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(ct, "video/") {
|
if strings.HasPrefix(contentType, "video/") {
|
||||||
return "video"
|
return "video"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Slower path for uppercase or mixed case
|
||||||
|
if contentType != "" {
|
||||||
|
ct := strings.ToLower(contentType)
|
||||||
|
if strings.HasPrefix(ct, "image/") {
|
||||||
|
return "image"
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(ct, "audio/") || ct == "application/ogg" {
|
||||||
|
return "audio"
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(ct, "video/") {
|
||||||
|
return "video"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback: infer from extension
|
// Fallback: infer from extension
|
||||||
ext := filepath.Ext(fn)
|
ext := filepath.Ext(filename)
|
||||||
switch ext {
|
if ext != "" {
|
||||||
case ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg":
|
// Only lower case the extension, which is usually just a few characters
|
||||||
return "image"
|
ext = strings.ToLower(ext)
|
||||||
case ".mp3", ".wav", ".ogg", ".m4a", ".flac", ".aac", ".wma", ".opus":
|
switch ext {
|
||||||
return "audio"
|
case ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg":
|
||||||
case ".mp4", ".avi", ".mov", ".webm", ".mkv":
|
return "image"
|
||||||
return "video"
|
case ".mp3", ".wav", ".ogg", ".m4a", ".flac", ".aac", ".wma", ".opus":
|
||||||
|
return "audio"
|
||||||
|
case ".mp4", ".avi", ".mov", ".webm", ".mkv":
|
||||||
|
return "video"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "file"
|
return "file"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue