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`
|
||||
**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.
|
||||
## 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,9 +102,20 @@ func formatToolsForLog(toolDefs []providers.ToolDefinition) string {
|
|||
// inferMediaType determines the media type ("image", "audio", "video", "file")
|
||||
// from a filename and MIME content type.
|
||||
func inferMediaType(filename, contentType string) string {
|
||||
ct := strings.ToLower(contentType)
|
||||
fn := strings.ToLower(filename)
|
||||
// Fast path for common, correctly cased content types
|
||||
if strings.HasPrefix(contentType, "image/") {
|
||||
return "image"
|
||||
}
|
||||
if strings.HasPrefix(contentType, "audio/") || contentType == "application/ogg" {
|
||||
return "audio"
|
||||
}
|
||||
if strings.HasPrefix(contentType, "video/") {
|
||||
return "video"
|
||||
}
|
||||
|
||||
// Slower path for uppercase or mixed case
|
||||
if contentType != "" {
|
||||
ct := strings.ToLower(contentType)
|
||||
if strings.HasPrefix(ct, "image/") {
|
||||
return "image"
|
||||
}
|
||||
|
|
@ -114,9 +125,13 @@ func inferMediaType(filename, contentType string) string {
|
|||
if strings.HasPrefix(ct, "video/") {
|
||||
return "video"
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: infer from extension
|
||||
ext := filepath.Ext(fn)
|
||||
ext := filepath.Ext(filename)
|
||||
if ext != "" {
|
||||
// Only lower case the extension, which is usually just a few characters
|
||||
ext = strings.ToLower(ext)
|
||||
switch ext {
|
||||
case ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg":
|
||||
return "image"
|
||||
|
|
@ -125,6 +140,7 @@ func inferMediaType(filename, contentType string) string {
|
|||
case ".mp4", ".avi", ".mov", ".webm", ".mkv":
|
||||
return "video"
|
||||
}
|
||||
}
|
||||
|
||||
return "file"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue