我想知道这是区别:
作为
string[] arrayOld = new string(){"This", "other", "aaa", ...};
string[] arrayNew = new string[arrayOld.lenght];
for(int i = i < arrayOld.lenght; i++){
arrayNew[i] = arrayOld[i];
}
FOREACH:
string[] arrayOld = new string(){"This", "other", "aaa", ...};
List<string> listNew = new List<string>();
foreach(string val in arrayOld){
listNew.add(val);
}
string[] arrayNew = listNew.toArray();
LINQ:
string[] arrayOld = new string(){"This", "other", "aaa", ...};
string[] arrayNew = (from val in arrayOld select val).toArray();
我不想复制数组......
这个想法是从arrayOld中的对象构造新对象(可以与string不同,并且可以包含其他属性......)
我需要表现,所以......
¿什么是最佳选择?为什么?
答案 0 :(得分:10)
以上都不是。
如果您正在尝试复制数组,我会尝试:
string[] arrayOld = new { "This", "other", "aaa" };
string[] arrayNew = new string[arrayOld.Length];
arrayOld.CopyTo(arrayNew, 0);
答案 1 :(得分:10)
原油结果最适合自己:
class Program
{
static void Main()
{
// Warm-up
Method1();
Method2();
Method3();
const int Count = 1000000;
var watch = Stopwatch.StartNew();
for (int i = 0; i < Count; i++)
{
Method1();
}
watch.Stop();
Console.WriteLine("Method1: {0} ms", watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < Count; i++)
{
Method2();
}
watch.Stop();
Console.WriteLine("Method2: {0} ms", watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < Count; i++)
{
Method3();
}
watch.Stop();
Console.WriteLine("Method3: {0} ms", watch.ElapsedMilliseconds);
}
static void Method1()
{
string[] arrayOld = new[] { "This", "other", "aaa" };
string[] arrayNew = new string[arrayOld.Length];
for (var i = 0; i < arrayOld.Length; i++)
{
arrayNew[i] = arrayOld[i];
}
}
static void Method2()
{
string[] arrayOld = new[] { "This", "other", "aaa" };
var listNew = new List<string>(arrayOld.Length);
foreach(var val in arrayOld)
{
listNew.Add(val);
}
string[] arrayNew = listNew.ToArray();
}
static void Method3()
{
string[] arrayOld = new[] { "This", "other", "aaa" };
string[] arrayNew = (from val in arrayOld select val).ToArray();
}
}
在我的机器上打印:
Method1: 72 ms
Method2: 187 ms
Method3: 377 ms
答案 2 :(得分:4)
在大多数情况下,您应该选择最清楚地表达您正在编写的特定代码的意图。然而,如果它是一个非常深的内循环,并且你需要每隔一个纳秒发出吱吱声,我的经验是(使用Release构建代码)一个for循环索引在一个数组上比一个foreach循环快得多,稍微小一点使用带有LINQ的委托与使用循环内部逻辑的简单foreach的性能损失。
这些观察结果基于AI中使用的分数计算算法的微优化工作,其中分数函数被评估许多次。使用性能分析工具确定了具体的瓶颈和改进程度,如果您处于这种情况,我强烈建议您使用。瓶颈很少在你认为的地方。
答案 3 :(得分:3)
至于性能for
可能会超过其他人,因为您直接使用索引器,foreach
使用Enumerator
,因此您需要执行更多行(GetEnumerator, MoveNext,Current等)..但差异是非常微妙并支付代码的可读性和可维护性。
至于LINQ还有很多工作要做。但想想LINQ为什么要更快?它还在内部使用循环。
大多数情况下,LINQ会慢一点,因为它会引入开销。如果您非常关心性能,请不要使用LINQ。使用LINQ是因为您需要更短的更易读和可维护的代码。
如果您对性能过于敏感并想要在每个最后一个时钟周期生成,那么您可能希望在 unsafe
中使用C样式指针带有fixed
变量的上下文
答案 4 :(得分:2)
最快的方式是Array.Copy
。
string[] arrayOld = new string[] { "This", "other", "aaa" };
string[] arrayNew = new string[arrayOld.Length];
Array.Copy(arrayOld, arrayNew, arrayOld.Length);
答案 5 :(得分:1)
建立Daniel A. White的评论,不确定它是否严重,但他是对的。你听说过StopWatch课吗?
我认为现在是时候让你花一点时间,学习如何判断自己的表现。如果我们其中一个人真的想要正确回答你的问题,我们就必须编写性能检查代码,这就是为什么你的问题可能会收到这么多的投票。因为你应该这样做。但我们会帮助你:)
您可以使用StopWatch类以及许多其他技术(计算时钟周期/迭代)来确定哪种方法具有最佳性能。
http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(10000); // put one of your three scenarios here
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);
}
}
(来自msdn的代码片段)