412 c# performance
我有DetailsView一个TextBox
和我想要的输入数据来始终保存的第一个字母注册资本.
例:
"red" --> "Red"
"red house" --> " Red house"
Run Code Online (Sandbox Code Playgroud)
如何实现这种最大化的性能?
注意:
根据答案和答案下的评论,很多人认为这是在询问字符串中所有单词的大写.例如,=> Red House 它不是,但如果这是你所追求的,寻找使用其中一个答案TextInfo的ToTitleCase方法.(注意:对于实际提出的问题,这些答案是不正确的.)
请参阅TextInfo.ToTitleCase doc以获取警告(不触及所有大写单词 - 它们被视为首字母缩略词;可以在"不应该"的单词中间小写字母降低,例如"麦当劳"=>"麦当劳";不保证能够处理所有特定文化的细微差别.
注意:
关于第一个字母之后的字母是否应该强制为小写,问题不明确.接受的答案假定只应改变第一个字母.如果要强制除第一个字符串之外的字符串中的所有字母都是小写,请查找包含但不包含ToTitleCase的答案.ToLower
Car*_*ñoz 524
编辑:更新为更新的语法(和更正确的答案),也作为扩展方法.
public static class StringExtensions
{
public static string FirstCharToUpper(this string input) =>
input switch
{
null => throw new ArgumentNullException(nameof(input)),
"" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
_ => input.First().ToString().ToUpper() + input.Substring(1)
}
}
}
Run Code Online (Sandbox Code Playgroud)
老答复
public static class StringExtensions
{
public static string FirstCharToUpper(this string input)
{
switch (input)
{
case null: throw new ArgumentNullException(nameof(input));
case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
default: return input.First().ToString().ToUpper() + input.Substring(1);
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:这个版本更短.如需更快的解决方案,请查看Equiso的答案
public static string FirstCharToUpper(string input)
{
if (String.IsNullOrEmpty(input))
throw new ArgumentException("ARGH!");
return input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
}
Run Code Online (Sandbox Code Playgroud)
编辑2:可能最快的解决方案是Darren(甚至还有一个基准),虽然我会更改它的string.IsNullOrEmpty(s)验证以抛出异常,因为原始要求期望第一个字母存在,因此它可以是大写的.请注意,此代码适用于通用字符串,而不是特别适用于来自的有效值Textbox.
Die*_*res 301
public string FirstLetterToUpper(string str)
{
if (str == null)
return null;
if (str.Length > 1)
return char.ToUpper(str[0]) + str.Substring(1);
return str.ToUpper();
}
Run Code Online (Sandbox Code Playgroud)
旧答案:这使得每个第一个字母大写
public string ToTitleCase(string str)
{
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}
Run Code Online (Sandbox Code Playgroud)
Pie*_*met 147
正确的方法是使用文化:
System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(word.ToLower())
Run Code Online (Sandbox Code Playgroud)
注意:这将大写字符串中的每个单词,例如"red house" - >"Red House".该解决方案还将在单词内进行小写大写,例如"老麦当劳" - >"老麦克唐纳".
Dar*_*ren 62
我从http://www.dotnetperls.com/uppercase-first-letter采用最快的方法并转换为扩展方法:
/// <summary>
/// Returns the input string with the first character converted to uppercase, or mutates any nulls passed into string.Empty
/// </summary>
public static string FirstLetterToUpperCaseOrConvertNullToEmptyString(this string s)
{
if (string.IsNullOrEmpty(s))
return string.Empty;
char[] a = s.ToCharArray();
a[0] = char.ToUpper(a[0]);
return new string(a);
}
Run Code Online (Sandbox Code Playgroud)
注意:使用的原因ToCharArray比替代方法更快char.ToUpper(s[0]) + s.Substring(1),是只Substring分配了一个字符串,而方法为子字符串分配了一个字符串,然后是第二个字符串来组成最终结果.
编辑:这是这种方法的样子,结合CarlosMuñoz的初步测试,接受了答案:
/// <summary>
/// Returns the input string with the first character converted to uppercase
/// </summary>
public static string FirstLetterToUpperCase(this string s)
{
if (string.IsNullOrEmpty(s))
throw new ArgumentException("There is no first letter");
char[] a = s.ToCharArray();
a[0] = char.ToUpper(a[0]);
return new string(a);
}
Run Code Online (Sandbox Code Playgroud)
İbr*_*lük 44
你可以使用"ToTitleCase方法"
string s = new CultureInfo("en-US").TextInfo.ToTitleCase("red house");
//result : Red House
Run Code Online (Sandbox Code Playgroud)
这种扩展方法解决了每个标题问题.
易于使用
string str = "red house";
str.ToTitleCase();
//result : Red house
string str = "red house";
str.ToTitleCase(TitleCase.All);
//result : Red House
Run Code Online (Sandbox Code Playgroud)
扩展方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace Test
{
public static class StringHelper
{
private static CultureInfo ci = new CultureInfo("en-US");
//Convert all first latter
public static string ToTitleCase(this string str)
{
str = str.ToLower();
var strArray = str.Split(' ');
if (strArray.Length > 1)
{
strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
return string.Join(" ", strArray);
}
return ci.TextInfo.ToTitleCase(str);
}
public static string ToTitleCase(this string str, TitleCase tcase)
{
str = str.ToLower();
switch (tcase)
{
case TitleCase.First:
var strArray = str.Split(' ');
if (strArray.Length > 1)
{
strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
return string.Join(" ", strArray);
}
break;
case TitleCase.All:
return ci.TextInfo.ToTitleCase(str);
default:
break;
}
return ci.TextInfo.ToTitleCase(str);
}
}
public enum TitleCase
{
First,
All
}
}
Run Code Online (Sandbox Code Playgroud)
Kob*_*obi 31
对于第一个字母,进行错误检查:
public string CapitalizeFirstLetter(string s)
{
if (String.IsNullOrEmpty(s))
return s;
if (s.Length == 1)
return s.ToUpper();
return s.Remove(1).ToUpper() + s.Substring(1);
}
Run Code Online (Sandbox Code Playgroud)
这里有一个方便的扩展
public static string CapitalizeFirstLetter(this string s)
{
if (String.IsNullOrEmpty(s)) return s;
if (s.Length == 1) return s.ToUpper();
return s.Remove(1).ToUpper() + s.Substring(1);
}
Run Code Online (Sandbox Code Playgroud)
Tar*_*nin 11
public static string ToInvarianTitleCase(this string self)
{
if (string.IsNullOrWhiteSpace(self))
{
return self;
}
return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(self);
}
Run Code Online (Sandbox Code Playgroud)
l33*_*33t 11
使用string.Create()并避免throw在我们的方法中使用关键字(是的,您没看错),我们可以更进一步地使用Marcell 的答案。此外,我的方法处理任意长度的字符串(例如,几兆字节的文本)。
public static string L33t(this string s)
{
static void ThrowError() => throw new ArgumentException("There is no first letter");
if (string.IsNullOrEmpty(s))
ThrowError(); // No "throw" keyword to avoid costly IL
return string.Create(s.Length, s, (chars, state) =>
{
state.AsSpan().CopyTo(chars); // No slicing to save some CPU cycles
chars[0] = char.ToUpper(chars[0]);
});
}
Run Code Online (Sandbox Code Playgroud)
以下是在.NET Core 3.1.7, 64 位上运行的基准测试的数字。我添加了一个更长的字符串来确定额外副本的成本。
| 方法 | 数据 | 意思 | 错误 | 标准差 | 中位数 |
|---|---|---|---|---|---|
| L33t | 红色的 | 8.545 纳秒 | 0.4612 纳秒 | 1.3308 纳秒 | 8.075 纳秒 |
| 马塞尔 | 红色的 | 9.153 纳秒 | 0.3377 纳秒 | 0.9471 纳秒 | 8.946 纳秒 |
| L33t | 红房子 | 7.715 纳秒 | 0.1741 纳秒 | 0.4618 纳秒 | 7.793 纳秒 |
| 马塞尔 | 红房子 | 10.537 纳秒 | 0.5002 纳秒 | 1.4351 纳秒 | 10.377 纳秒 |
| L33t | 红色 r(...)house [89] | 11.121 纳秒 | 0.6774 纳秒 | 1.9106 纳秒 | 10.612 纳秒 |
| 马塞尔 | 红色 r(...)house [89] | 16.739 纳秒 | 0.4468 纳秒 | 1.3033 纳秒 | 16.853 纳秒 |
using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
namespace CorePerformanceTest
{
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<StringUpperTest>();
}
}
public class StringUpperTest
{
[Params("red", "red house", "red red red red red red red red red red red red red red red red red red red red red house")]
public string Data;
[Benchmark]
public string Marcell() => Data.Marcell();
[Benchmark]
public string L33t() => Data.L33t();
}
internal static class StringExtensions
{
public static string Marcell(this string s)
{
if (string.IsNullOrEmpty(s))
throw new ArgumentException("There is no first letter");
Span<char> a = stackalloc char[s.Length];
s.AsSpan(1).CopyTo(a.Slice(1));
a[0] = char.ToUpper(s[0]);
return new string(a);
}
public static string L33t(this string s)
{
static void ThrowError() => throw new ArgumentException("There is no first letter");
if (string.IsNullOrEmpty(s))
ThrowError(); // IMPORTANT: Do not "throw" here!
return string.Create(s.Length, s, (chars, state) =>
{
state.AsSpan().CopyTo(chars);
chars[0] = char.ToUpper(chars[0]);
});
}
}
}
Run Code Online (Sandbox Code Playgroud)
请让我知道你是否可以让它更快!
小智 9
最快的方法:
private string Capitalize(string s){
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
char[] a = s.ToCharArray();
a[0] = char.ToUpper(a[0]);
return new string(a);
}
Run Code Online (Sandbox Code Playgroud)
测试显示下一个结果(输入为 1,0000,000 个符号的字符串):
由于这个问题是关于最大化性能,我采用了达伦的版本使用Spans,减少了垃圾并提高了10%左右的速度。
/// <summary>
/// Returns the input string with the first character converted to uppercase
/// </summary>
public static string ToUpperFirst(this string s)
{
if (string.IsNullOrEmpty(s))
throw new ArgumentException("There is no first letter");
Span<char> a = stackalloc char[s.Length];
s.AsSpan(1).CopyTo(a.Slice(1));
a[0] = char.ToUpper(s[0]);
return new string(a);
}
Run Code Online (Sandbox Code Playgroud)
| 方法 | 数据 | 意思 | 错误 | 标准差 |
|---|---|---|---|---|
| 卡洛斯 | 红色的 | 107.29 纳秒 | 2.2401 纳秒 | 3.9234 纳秒 |
| 达伦 | 红色的 | 30.93 纳秒 | 0.9228 纳秒 | 0.8632 纳秒 |
| 马塞尔 | 红色的 | 26.99 纳秒 | 0.3902 纳秒 | 0.3459 纳秒 |
| 卡洛斯 | 红房子 | 106.78 纳秒 | 1.9713 纳秒 | 1.8439 纳秒 |
| 达伦 | 红房子 | 32.49 纳秒 | 0.4253 纳秒 | 0.3978 纳秒 |
| 马塞尔 | 红房子 | 27.37 纳秒 | 0.3888 纳秒 | 0.3637 纳秒 |
using System;
using System.Linq;
using BenchmarkDotNet.Attributes;
namespace CorePerformanceTest
{
public class StringUpperTest
{
[Params("red", "red house")]
public string Data;
[Benchmark]
public string Carlos() => Data.Carlos();
[Benchmark]
public string Darren() => Data.Darren();
[Benchmark]
public string Marcell() => Data.Marcell();
}
internal static class StringExtensions
{
public static string Carlos(this string input) =>
input switch
{
null => throw new ArgumentNullException(nameof(input)),
"" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
_ => input.First().ToString().ToUpper() + input.Substring(1)
};
public static string Darren(this string s)
{
if (string.IsNullOrEmpty(s))
throw new ArgumentException("There is no first letter");
char[] a = s.ToCharArray();
a[0] = char.ToUpper(a[0]);
return new string(a);
}
public static string Marcell(this string s)
{
if (string.IsNullOrEmpty(s))
throw new ArgumentException("There is no first letter");
Span<char> a = stackalloc char[s.Length];
s.AsSpan(1).CopyTo(a.Slice(1));
a[0] = char.ToUpper(s[0]);
return new string(a);
}
}
}
Run Code Online (Sandbox Code Playgroud)
尝试这个:
static public string UpperCaseFirstCharacter(this string text) {
return Regex.Replace(text, "^[a-z]", m => m.Value.ToUpper());
}
Run Code Online (Sandbox Code Playgroud)
小智 6
如果性能/内存使用是一个问题,那么这个只创建一(1)个StringBuilder和一(1)个与原始字符串大小相同的新String.
public static string ToUpperFirst(this string str) {
if( !string.IsNullOrEmpty( str ) ) {
StringBuilder sb = new StringBuilder(str);
sb[0] = char.ToUpper(sb[0]);
return sb.ToString();
} else return str;
}
Run Code Online (Sandbox Code Playgroud)
由于我碰巧也在做这方面的工作,并且正在四处寻找任何想法,这就是我找到的解决方案。它使用 LINQ,并且能够将字符串的第一个字母大写,即使第一次出现的不是字母。这是我最终制作的扩展方法。
public static string CaptalizeFirstLetter(this string data)
{
var chars = data.ToCharArray();
// Find the Index of the first letter
var charac = data.First(char.IsLetter);
var i = data.IndexOf(charac);
// capitalize that letter
chars[i] = char.ToUpper(chars[i]);
return new string(chars);
}
Run Code Online (Sandbox Code Playgroud)
我相信有一种方法可以稍微优化或清理它。
小智 6
如果您只关心第一个字母是否大写,而字符串的其余部分无关紧要,则只需选择第一个字符,将其设为大写,然后将其与没有原始第一个字符的字符串的其余部分连接起来。
String word ="red house";
word = word[0].ToString().ToUpper() + word.Substring(1, word.length -1);
//result: word = "Red house"
Run Code Online (Sandbox Code Playgroud)
我们需要将第一个字符转换成ToString(),因为我们是把它读成一个Char数组,而Char类型没有ToUpper()方法。
检查字符串是否不为空,将第一个字符转换为大写,其余字符转换为小写:
public static string FirstCharToUpper(string str)
{
return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
}
Run Code Online (Sandbox Code Playgroud)
这是一种作为扩展方法来执行此操作的方法:
static public string UpperCaseFirstCharacter(this string text)
{
if (!string.IsNullOrEmpty(text))
{
return string.Format(
"{0}{1}",
text.Substring(0, 1).ToUpper(),
text.Substring(1));
}
return text;
}
Run Code Online (Sandbox Code Playgroud)
然后可以这样调用它:
//yields "This is Brian's test.":
"this is Brian's test.".UpperCaseFirstCharacter();
Run Code Online (Sandbox Code Playgroud)
这是它的一些单元测试:
[Test]
public void UpperCaseFirstCharacter_ZeroLength_ReturnsOriginal()
{
string orig = "";
string result = orig.UpperCaseFirstCharacter();
Assert.AreEqual(orig, result);
}
[Test]
public void UpperCaseFirstCharacter_SingleCharacter_ReturnsCapital()
{
string orig = "c";
string result = orig.UpperCaseFirstCharacter();
Assert.AreEqual("C", result);
}
[Test]
public void UpperCaseFirstCharacter_StandardInput_CapitalizeOnlyFirstLetter()
{
string orig = "this is Brian's test.";
string result = orig.UpperCaseFirstCharacter();
Assert.AreEqual("This is Brian's test.", result);
}
Run Code Online (Sandbox Code Playgroud)
我在C# 大写首字母 - Dot Net Perls中发现了一些内容:
static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
450738 次 |
| 最近记录: |