我在下面的代码中运行良好,可以找到列表中彼此之间相似度为±2的项目。我想使用2个版本来检查哪个版本运行速度更快。
版本a)具有嵌套的For循环,如下代码。但是,代码的最后一部分具有!List.Contains(),我希望将其替换为另一个For循环,因为Contains()增加了4500个滴答声,而其他2个嵌套的for循环仅需要1500个滴答声。因此,如果有人可以帮助用另一个for循环替换Contains()并提供相同的结果,我将不胜感激。
版本b),但使用LINQ。
在两个版本中,输出列表intTestResult中的项目必须为:(1、2、8、9、10、12)
int intOffset = 2;
List<int> intTest = new List<int> { 1, 2, 5, 8, 9, 10, 12, 15, 19, 24 };
List<int> intTestResult = new List<int>();
var S1 = Stopwatch.StartNew();
for (int a = 0; a < intTest.Count; a++)
{
int int1 = intTest[a];
for (int b = 0; b < intTest.Count; b++)
{
int int2 = intTest[b];
if (int1 + intOffset >= int2 && int1 - intOffset <= int2 && int1 != int2)
{
if (!intTestResult.Contains(int1))
intTestResult.Add(int1);
}
}
}
S1.Stop();
Console.WriteLine("Ticks = " + S1.ElapsedTicks);
/ *经历过壁虱6000
intTestResult项目为(1、2、8、9、10、12)* /
答案 0 :(得分:1)
替换:
if (!intTestResult.Contains(int1))
intTestResult.Add(int1);
使用
bool contains = false;
for(int c = 0; c < intTestResult.Count; c++)
{
if(int1 == intTestResult[c])
{
contains = true;
break;
}
}
if(!contains)
intTestResult.Add(int1);
答案 1 :(得分:1)
害怕衡量效果的方法是错误的。
首先,您应该多次执行方法,例如在循环中。因为首次执行将始终花费更多时间,并且可能可以从计算中排除首次循环。
使用大量数据进行处理。许多有效的数据结构在处理少量数据时速度较慢,而处理大量数据时速度很快。
如果您的应用程序无法处理大量数据,那么您根本不需要测试性能。 只需编写对其他开发人员(您自己)来说都易于阅读和理解的代码。我会说“写出可以被人脑快速处理的代码”。
使用HashSet<int>
和Enumerable.Aggregate
的方法
// Helper method to check if two numbers within offset
private IEnumerable<int> WithinOffset(int? previous, int current, int offset)
{
if (previous.HasValue == false)
{
yield break;
}
var difference = Math.Abs(previous.Value, current);
if (difference > 0 && difference <= offset)
{
yield return previous.Value;
yield return current;
}
}
var clock = Stopwatch.Start();
var offset = 2;
var result =
givenData.OrderBy(number => number)
.Aggregate(
(All: Enumerable.Empty<int>(), Last: default(int?)),
(summary, current) =>
{
var withinOffset = WithinOffset(summery.Last, current, offset);
var all = summary.All.Concat(withinOffset);
return (all, current);
},
(summary) => summary.All.ToHashSet().ToList());
clock.Stop();
var ticks = clock.ElapsedTicks;
如果我按照您的方法进行测量,但会提供包含1000个项目的列表
var template = new[] { 1, 2, 5, 8, 9, 10, 12, 15, 19, 24 }
var givenData =
Enumerable.Range(0, 100)
.Select(i => i * 100)
.Select(i => template.Select(number => number + i))
.SelectMany(number => number)
.ToList();
// Approach with accepted answer
// Elapsed ticks = 11517000 (1.1517 seconds)
// Approach with HashSet, OrderBy and Aggregate
// Elapsed ticks = 2202000 (0.2202 seconds)