[PR #15916] [MERGED] Optimize StringHelper.FirstToUpper() #14466

Closed
opened 2026-02-07 07:30:15 +03:00 by OVERLORD · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/jellyfin/jellyfin/pull/15916
Author: @stevenaw
Created: 12/31/2025
Status: Merged
Merged: 1/3/2026
Merged by: @Bond-009

Base: masterHead: optimize-tofirstupper


📝 Commits (1)

  • e5fb071 Optimize StringHelper.ToFirstUpper()

📊 Changes

1 file changed (+4 additions, -5 deletions)

View changed files

📝 MediaBrowser.Model/Extensions/StringHelper.cs (+4 -5)

📄 Description

Optimize StringHelper.FirstToUpper(). This is primarily used at the moment to ensure the CultureInfo.DisplayName, when included in the MediaStream's DisplayTitle, will always have a leading capital.

Changes
Change an iterative char-by-char copy to a block copy. On my machine there is a small 1ns performance penalty for the single-character case but already at a 5-character string this optimized version runs in 80% of the time. A 25-character string is almost 2x as fast as the original implementation. I would expect any usages of this which pass in a language's DisplayName to usually be at least 5 or more characters long.

| Method    | Length | Mean     | Error     | StdDev    | Ratio | RatioSD | Gen0   | Code Size | Allocated | Alloc Ratio |
|---------- |------- |---------:|----------:|----------:|------:|--------:|-------:|----------:|----------:|------------:|
| Original  | 1      | 2.627 ns | 0.0424 ns | 0.0375 ns |  1.00 |    0.02 | 0.0038 |     559 B |      24 B |        1.00 |
| Optimized | 1      | 3.770 ns | 0.0450 ns | 0.0421 ns |  1.44 |    0.03 | 0.0038 |     919 B |      24 B |        1.00 |
|           |        |          |           |           |       |         |        |           |           |             |
| Original  | 5      | 4.842 ns | 0.0647 ns | 0.0540 ns |  1.00 |    0.02 | 0.0051 |     594 B |      32 B |        1.00 |
| Optimized | 5      | 3.777 ns | 0.0336 ns | 0.0314 ns |  0.78 |    0.01 | 0.0051 |     919 B |      32 B |        1.00 |
|           |        |          |           |           |       |         |        |           |           |             |
| Original  | 25     | 8.610 ns | 0.0413 ns | 0.0387 ns |  1.00 |    0.01 | 0.0115 |     612 B |      72 B |        1.00 |
| Optimized | 25     | 4.727 ns | 0.0400 ns | 0.0375 ns |  0.55 |    0.00 | 0.0115 |     908 B |      72 B |        1.00 |

Issues
Fixes https://github.com/jellyfin/jellyfin/issues/15915


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/jellyfin/jellyfin/pull/15916 **Author:** [@stevenaw](https://github.com/stevenaw) **Created:** 12/31/2025 **Status:** ✅ Merged **Merged:** 1/3/2026 **Merged by:** [@Bond-009](https://github.com/Bond-009) **Base:** `master` ← **Head:** `optimize-tofirstupper` --- ### 📝 Commits (1) - [`e5fb071`](https://github.com/jellyfin/jellyfin/commit/e5fb07170888f5c77df9a686b1a73bafae26c784) Optimize StringHelper.ToFirstUpper() ### 📊 Changes **1 file changed** (+4 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `MediaBrowser.Model/Extensions/StringHelper.cs` (+4 -5) </details> ### 📄 Description Optimize `StringHelper.FirstToUpper()`. This is primarily used at the moment to ensure the `CultureInfo.DisplayName`, when included in the MediaStream's `DisplayTitle`, will always have a leading capital. **Changes** Change an iterative char-by-char copy to a block copy. On my machine there is a small 1ns performance penalty for the single-character case but already at a 5-character string this optimized version runs in 80% of the time. A 25-character string is almost 2x as fast as the original implementation. I would expect any usages of this which pass in a language's `DisplayName` to usually be at least 5 or more characters long. ``` | Method | Length | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Code Size | Allocated | Alloc Ratio | |---------- |------- |---------:|----------:|----------:|------:|--------:|-------:|----------:|----------:|------------:| | Original | 1 | 2.627 ns | 0.0424 ns | 0.0375 ns | 1.00 | 0.02 | 0.0038 | 559 B | 24 B | 1.00 | | Optimized | 1 | 3.770 ns | 0.0450 ns | 0.0421 ns | 1.44 | 0.03 | 0.0038 | 919 B | 24 B | 1.00 | | | | | | | | | | | | | | Original | 5 | 4.842 ns | 0.0647 ns | 0.0540 ns | 1.00 | 0.02 | 0.0051 | 594 B | 32 B | 1.00 | | Optimized | 5 | 3.777 ns | 0.0336 ns | 0.0314 ns | 0.78 | 0.01 | 0.0051 | 919 B | 32 B | 1.00 | | | | | | | | | | | | | | Original | 25 | 8.610 ns | 0.0413 ns | 0.0387 ns | 1.00 | 0.01 | 0.0115 | 612 B | 72 B | 1.00 | | Optimized | 25 | 4.727 ns | 0.0400 ns | 0.0375 ns | 0.55 | 0.00 | 0.0115 | 908 B | 72 B | 1.00 | ``` **Issues** Fixes https://github.com/jellyfin/jellyfin/issues/15915 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
OVERLORD added the pull-request label 2026-02-07 07:30:15 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/jellyfin#14466