字符串输出:C#格式或concat?
假设您想要输出或压缩字符串。您喜欢以下哪种款式字符串输出:C#格式或concat?,c#,string,coding-style,string.format,C#,String,Coding Style,String.format,假设您想要输出或压缩字符串。您喜欢以下哪种款式 var p=new{FirstName=“Bill”,LastName=“Gates”} Console.WriteLine(“{0}{1}”,p.FirstName,p.LastName) Console.WriteLine(p.FirstName+“”+p.LastName) 您是更喜欢使用格式还是只使用concat字符串?你最喜欢什么?其中一个会伤到你的眼睛吗 你有没有合理的理由使用其中一个而不是另一个 我会选择第二个。就我个人而言,第二
var p=new{FirstName=“Bill”,LastName=“Gates”}代码>
Console.WriteLine(“{0}{1}”,p.FirstName,p.LastName)代码>
Console.WriteLine(p.FirstName+“”+p.LastName)代码>
我会选择第二个。就我个人而言,第二个是因为您使用的所有东西都是按直接顺序输出的。而对于第一个变量,您必须将{0}和{1}与适当的var相匹配,这很容易出错 <>至少它不如C++ SpaveTF那么坏,如果你得到变量类型错误,整个事情就会爆炸。
另外,由于第二个是内联的,它不必对所有{0}事物进行任何搜索和替换,因此后者应该更快。。。虽然我不确定。我认为这在很大程度上取决于输出的复杂程度。我倾向于选择当时效果最好的方案
根据作业选择正确的工具:D,以看起来最干净的为准 对于非常简单的操作,我会使用串联,但一旦超过2或3个元素,格式就变得更合适了
选择String.Format的另一个原因是.NET字符串是不可变的,这样做会创建较少的临时/中间副本。我也喜欢第二个,但目前我没有支持该位置的合理参数。通常我更喜欢前者,尤其是当字符串变长时,它更容易阅读 我认为另一个好处是性能,因为后者在将最后一个字符串传递给Console.Write方法之前实际上执行了两个字符串创建语句。Format在封面下使用了StringBuilder,因此避免了多次连接
但是,应该注意的是,如果传递给String.Format(以及其他类似于Console.Write的方法)的参数是值类型,那么它们在传递之前将被装箱,这可以提供其自身的性能影响 对于基本字符串连接,我通常使用第二种样式-更容易阅读和更简单。但是,如果我要进行更复杂的字符串组合,我通常会选择string.Format 格式保存了大量的引号和加号
Console.WriteLine("User {0} accessed {1} on {2}.", user.Name, fileName, timestamp);
vs
Console.WriteLine("User " + user.Name + " accessed " + fileName + " on " + timestamp + ".");
虽然只保存了几个字符,但我认为,在本例中,格式使其更加清晰。在这样一个简单的场景中,连接字符串是很好的-任何比这更复杂的东西都更复杂,即使是LastName,FirstName。使用这种格式,您可以一目了然地看到在读取代码时字符串的最终结构是什么,通过串联,几乎不可能立即识别最终结果(除了像这样一个非常简单的示例) 从长远来看,这意味着,当您回来更改字符串格式时,您将能够弹出并对格式字符串进行一些调整,或者皱起眉头,开始在混合了文本的各种属性访问器之间移动,这更可能带来问题 如果您使用的是.NET 3.5,则可以使用扩展方法,并获得一种简单流畅的即兴语法,如下所示:
string str = "{0} {1} is my friend. {3}, {2} is my boss.".FormatWith(prop1,prop2,prop3,prop4);
最后,随着应用程序复杂性的增加,您可能会决定,要在应用程序中合理地维护字符串,您需要将它们移动到资源文件中以进行本地化,或者只是移动到静态帮助器中。如果您一直使用格式,那么这将更容易实现,并且您的代码可以非常简单地进行重构以使用
string name = String.Format(ApplicationStrings.General.InformalUserNameFormat,this.FirstName,this.LastName);
实际上,我喜欢第一个,因为当文本中有很多变量时,我似乎更容易阅读。另外,使用string.Format(),呃,Format时更容易处理引号。下面是字符串连接的示例
虽然我完全理解风格偏好,并在我的第一个答案中选择了连接,部分是基于我自己的偏好,但我的部分决定是基于连接会更快的想法。因此,出于好奇,我对它进行了测试,结果令人震惊,尤其是对于这样一根小绳子 使用以下代码:
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
var p = new { FirstName = "Bill", LastName = "Gates" };
s.Start();
Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
s.Stop();
Console.WriteLine("Console.WriteLine(\"{0} {1}\", p.FirstName, p.LastName); took: " + s.ElapsedMilliseconds + "ms - " + s.ElapsedTicks + " ticks");
s.Reset();
s.Start();
Console.WriteLine(p.FirstName + " " + p.LastName);
s.Stop();
Console.WriteLine("Console.WriteLine(p.FirstName + \" \" + p.LastName); took: " + s.ElapsedMilliseconds + "ms - " + s.ElapsedTicks + " ticks");
我得到了以下结果:
Bill Gates
Console.WriteLine("{0} {1}", p.FirstName, p.LastName); took: 2ms - 7280 ticks
Bill Gates
Console.WriteLine(p.FirstName + " " + p.LastName); took: 0ms - 67 ticks
使用格式化方法的速度要慢100多倍!!连接甚至没有注册为1ms,这就是为什么我也会输出计时器的节拍。我会使用String.Format,但我也会在资源文件中使用Format字符串,这样它就可以被其他语言本地化。使用简单的字符串concat不允许这样做。显然,如果您不需要对该字符串进行本地化,那么就没有理由考虑这个问题。这真的取决于我使用的字符串
Console.WriteLine(String.Concat(p.FirstName," ",p.LastName));
Bill Gates
Console.WriteLine(p.FirstName + " " + p.LastName); took: 8ms - 30488 ticks
Bill Gates
Console.WriteLine("{0} {1}", p.FirstName, p.LastName); took: 0ms - 182 ticks
Bill Gates
Console.WriteLine(FirstName + " " + LastName); took: 5ms - 20335 ticks
Bill Gates
Console.WriteLine(FirstName + " " + LastName); took: 0ms - 156 ticks
Bill Gates
Console.WriteLine(FirstName + " " + LastName); took: 0ms - 122 ticks
Bill Gates
Console.WriteLine("{0} {1}", FirstName, LastName); took: 0ms - 181 ticks
Bill Gates
Console.WriteLine("{0} {1}", FirstName, LastName); took: 0ms - 122 ticks
Bill Gates
String.Concat(FirstName, " ", LastName); took: 0ms - 142 ticks
Bill Gates
String.Concat(FirstName, " ", LastName); took: 0ms - 117 ticks
Console.WriteLine("{0} {1}", p.FirstName, p.LastName); took (avg): 0ms - 689 ticks
Console.WriteLine(p.FirstName + " " + p.LastName); took (avg): 0ms - 683 ticks
Stopwatch s = new Stopwatch();
var p = new { FirstName = "Bill", LastName = "Gates" };
//First print to remove the initial cost
Console.WriteLine(p.FirstName + " " + p.LastName);
Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
int n = 100000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;
for (var i = 0; i < n; i++)
{
s.Start();
Console.WriteLine(p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds += s.ElapsedMilliseconds;
cElapsedTicks += s.ElapsedTicks;
s.Reset();
s.Start();
Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds += s.ElapsedMilliseconds;
fElapsedTicks += s.ElapsedTicks;
s.Reset();
}
Console.Clear();
Console.WriteLine("Console.WriteLine(\"{0} {1}\", p.FirstName, p.LastName); took (avg): " + (fElapsedMilliseconds / n) + "ms - " + (fElapsedTicks / n) + " ticks");
Console.WriteLine("Console.WriteLine(p.FirstName + \" \" + p.LastName); took (avg): " + (cElapsedMilliseconds / n) + "ms - " + (cElapsedTicks / n) + " ticks");
Stopwatch s = new Stopwatch();
var p = new { FirstName = "Bill", LastName = "Gates" };
int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;
string result;
s.Start();
for (var i = 0; i < n; i++)
result = (p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
result = string.Format("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();
Console.Clear();
Console.WriteLine(n.ToString()+" x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Thread.Sleep(4000);
s.Start();
for (var i = 0; i < n; i++)
result = string.Concat(p.FirstName, " ", p.LastName);
s.Stop();
ceElapsedMilliseconds = s.ElapsedMilliseconds;
ceElapsedTicks = s.ElapsedTicks;
s.Reset();
1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 249ms - 3571621 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 65ms - 944948 ticks
1000000 x result = string.Concat(p.FirstName, " ", p.LastName); took: 54ms - 780524 ticks
class Program {
static void Main(string[] args) {
var p = new { FirstName = "Bill", LastName = "Gates" };
var tests = new[] {
new { Name = "Concat", Action = new Action(delegate() { string x = p.FirstName + " " + p.LastName; }) },
new { Name = "Format", Action = new Action(delegate() { string x = string.Format("{0} {1}", p.FirstName, p.LastName); }) },
new { Name = "StringBuilder", Action = new Action(delegate() {
StringBuilder sb = new StringBuilder();
sb.Append(p.FirstName);
sb.Append(" ");
sb.Append(p.LastName);
string x = sb.ToString();
}) }
};
var Watch = new Stopwatch();
foreach (var t in tests) {
for (int i = 0; i < 5; i++) {
Watch.Reset();
long Elapsed = ElapsedTicks(t.Action, Watch, 10000);
Console.WriteLine(string.Format("{0}: {1} ticks", t.Name, Elapsed.ToString()));
}
}
}
public static long ElapsedTicks(Action ActionDelg, Stopwatch Watch, int Iterations) {
Watch.Start();
for (int i = 0; i < Iterations; i++) {
ActionDelg();
}
Watch.Stop();
return Watch.ElapsedTicks / Iterations;
}
}
Concat: 406 ticks
Concat: 356 ticks
Concat: 411 ticks
Concat: 299 ticks
Concat: 266 ticks
Format: 5269 ticks
Format: 954 ticks
Format: 1004 ticks
Format: 984 ticks
Format: 974 ticks
StringBuilder: 629 ticks
StringBuilder: 484 ticks
StringBuilder: 482 ticks
StringBuilder: 508 ticks
StringBuilder: 504 ticks
Console.WriteLine("User {0} accessed {1} on {2}.",
user.Name, fileName, timestamp);
Console.WriteLine("User " + user.Name + " accessed " + fileName +
" on " + timestamp + ".");
Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
Console.WriteLine(p.FirstName + " " + p.LastName);
Stopwatch s = new Stopwatch();
int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0, sbElapsedMilliseconds = 0, sbElapsedTicks = 0;
Random random = new Random(DateTime.Now.Millisecond);
string result;
s.Start();
for (var i = 0; i < n; i++)
result = (random.Next().ToString() + " " + random.Next().ToString());
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
result = string.Format("{0} {1}", random.Next().ToString(), random.Next().ToString());
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();
StringBuilder sb = new StringBuilder();
s.Start();
for(var i = 0; i < n; i++){
sb.Clear();
sb.Append(random.Next().ToString());
sb.Append(" ");
sb.Append(random.Next().ToString());
result = sb.ToString();
}
s.Stop();
sbElapsedMilliseconds = s.ElapsedMilliseconds;
sbElapsedTicks = s.ElapsedTicks;
s.Reset();
Console.WriteLine(n.ToString() + " x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x sb.Clear();sb.Append(random.Next().ToString()); sb.Append(\" \"); sb.Append(random.Next().ToString()); result = sb.ToString(); took: " + (sbElapsedMilliseconds) + "ms - " + (sbElapsedTicks) + " ticks");
Console.WriteLine("****************");
Console.WriteLine("Press Enter to Quit");
Console.ReadLine();
1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 513ms - 1499816 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 393ms - 1150148 ticks
1000000 x sb.Clear();sb.Append(random.Next().ToString()); sb.Append(" "); sb.Append(random.Next().ToString()); result = sb.ToString(); took: 405ms - 1185816 ticks
string s = a + "foo" + b;
string tmp1 = a;
string tmp2 = "foo"
string tmp3 = concat(tmp1, tmp2);
string tmp4 = b;
string s = concat(tmp3, tmp4);
var name = "Bill";
var surname = "Gates";
MessageBox.Show($"Welcome to the show, {name} {surname}!");
var p = new { FirstName = "Bill", LastName = "Gates" };
var fullname = $"{p.FirstName} {p.LastName}";
var qs = string.Format("q1={0}&q2={1}&q3={2}&q4={3}&q5={4}&q6={5}",
someVar, anotherVarWithLongName, var3, var4, var5, var6)
var qs=$"q1={someVar}&q2={anotherVarWithLongName}&q3={var3}&q4={var4}&q5={var5}&q6={var6}";