我的问题似乎无法找到答案:为什么如果我更改了调用包含.AsParallel()
和不包含或具有不同选项的方法的顺序,为什么呢?不一样。
我已将源代码放置在GitHub上,因此我无法覆盖所有屏幕-> https://github.com/moisoiu/asParallel
以及到目前为止我如何测试的一些说明。
我正在使用其他类生成一些随机数据,从那时起,我将生成的和随机化的数据传递给ParallelThreading
方法,并通过StopWatch
类测量时间并存储结果在字典中显示响应时间。
起初,我认为性能时间问题可能是因为我在同一个引用上工作,所以我创建了4个新对象 something ,它是一个数组,因此将有一个新的参考,但结果相同。
在某个时候,我什至甚至假设 watch 中的变量仍然可以存储上一个变量的值,所以我为每个变量都创建了一个新变量
有什么想法吗?
只需从Program.cs中选择一种方法,然后将其与其他方法交换,响应时间将几乎相同,但是使用时间最长的方法将是TOP上的方法,而使用时间最少的方法将是底部的方法。 。
编辑: 为了尊重来自以下评论的建议。我已经附加了部分源代码,以防万一,如果需要更多,我将更新并从上面的Git中删除链接。
Program.cs
class Program
{
static void Main(string[] args)
{
var parallelThreading = new ParallelThreading();
long elapsedMs = 0;
Dictionary<string, long> results = new Dictionary<string, long>();
var dataResults = parallelThreading.InitializeDataForParallelData(6500);
var something = new PersonModel[6500];
var something1 = new PersonModel[6500];
var something2 = new PersonModel[6500];
var something3 = new PersonModel[6500];
dataResults.CopyTo(something);
dataResults.CopyTo(something1);
dataResults.CopyTo(something2);
dataResults.CopyTo(something3);
var watch2 = System.Diagnostics.Stopwatch.StartNew();
parallelThreading.AsParallelAddingParallelization(something1.ToList());
watch2.Stop();
elapsedMs = watch2.ElapsedMilliseconds;
results.Add(nameof(parallelThreading.AsParallelAddingParallelization), elapsedMs);
var watch = System.Diagnostics.Stopwatch.StartNew();
parallelThreading.AsParallel(something2.ToList());
watch.Stop();
elapsedMs = watch.ElapsedMilliseconds;
results.Add(nameof(parallelThreading.AsParallel), elapsedMs);
var watch1 = System.Diagnostics.Stopwatch.StartNew();
parallelThreading.WithoutAsParallel(something3.ToList());
watch1.Stop();
elapsedMs = watch1.ElapsedMilliseconds;
results.Add(nameof(parallelThreading.WithoutAsParallel), elapsedMs);
var watch3 = System.Diagnostics.Stopwatch.StartNew();
parallelThreading.AsParallelAsOrdered(something.ToList());
watch3.Stop();
elapsedMs = watch3.ElapsedMilliseconds;
results.Add(nameof(parallelThreading.AsParallelAsOrdered), elapsedMs);
foreach (var result in results)
{
WriteTime(result.Key, result.Value);
}
Console.ReadLine();
}
private static void WriteTime(string methodName, long elapsedMiliseconds)
{
Console.WriteLine($" {methodName}: Milisecond passed: { elapsedMiliseconds}");
}
}
ParallelThreading.cs
public class ParallelThreading
{
private List<PersonModel> RandomData(int range)
{
List<PersonModel> personModels = new List<PersonModel>();
for (int i = 0; i < range; i++)
{
var person = new PersonModel()
{
NumberIdentification = i,
Age = Convert.ToInt32(GenerateString.RandomNumbers(2)),
DateOfBirth = GenerateString.GenerateDateTime(),
LastName = GenerateString.RandomString(10),
Name = GenerateString.RandomString(10),
City = GenerateString.RandomString(10)
};
personModels.Add(person);
}
return personModels;
}
private List<PersonModel> RandomDataWithSpecificSameData(int range, string city)
{
List<PersonModel> personModels = new List<PersonModel>();
for (int i = 0; i < range; i++)
{
var person = new PersonModel();
if (GenerateString.random.Next(range - 1) % 2 == 0)
{
person = new PersonModel()
{
NumberIdentification = i,
Age = Convert.ToInt32(GenerateString.RandomNumbers(2)),
DateOfBirth = GenerateString.GenerateDateTime(),
LastName = GenerateString.RandomString(10),
Name = GenerateString.RandomString(10),
City = city
};
}
else
{
person = new PersonModel()
{
NumberIdentification = i,
Age = Convert.ToInt32(GenerateString.RandomNumbers(2)),
DateOfBirth = GenerateString.GenerateDateTime(),
LastName = GenerateString.RandomString(10),
Name = GenerateString.RandomString(10),
City = GenerateString.RandomString(10),
};
}
personModels.Add(person);
}
return personModels;
}
#region AsParallelLINQ
public List<PersonModel> InitializeDataForParallelData(int range)
{
return RandomDataWithSpecificSameData(range, "Oradea");
}
public void AsParallel(List<PersonModel> data)
{
var result = data
.AsParallel()
.Where(c => c.City == "Oradea")
.Select(c => c);
foreach (var person in result)
{
Console.WriteLine($"{person.NumberIdentification} + {person.Name} + {person.City}");
}
}
public void AsParallelAddingParallelization(List<PersonModel> data)
{
var result = data
.AsParallel()
.WithDegreeOfParallelism(8)
.WithExecutionMode(ParallelExecutionMode.ForceParallelism)
.Where(c => c.City == "Oradea")
.Select(c => c);
foreach (var person in result)
{
Console.WriteLine($"{person.NumberIdentification} + {person.Name} + {person.City}");
}
}
public void AsParallelAsOrdered(List<PersonModel> data)
{
var result = data
.AsParallel()
.AsOrdered()
.Where(c => c.City == "Oradea")
.Select(c => c);
foreach (var person in result)
{
Console.WriteLine($"{person.NumberIdentification} + {person.Name} + {person.City}");
}
}
public void WithoutAsParallel(List<PersonModel> data)
{
var result = data.Where(c => c.City == "Oradea").Select(c => c);
foreach (var person in result)
{
Console.WriteLine($"{person.NumberIdentification} + {person.Name} + {person.City}");
}
}
#endregion
}
答案 0 :(得分:1)
首先感谢@mjwills和@Oliver所提供的帮助和链接。
在刮擦BenchmarkDotNet的表面(有大量选项)并对该解决方案进行了一些调整之后,看来(至少)就我而言,这两种方法之间没有区别(但是那是一个不同的问题,关于如何,何时以及以何种类型的数据使用AsParallel来获得性能。
第一篇文章的评论摘要: 我担心的是,即使我交换了这些方法(例如,从底部开始的最后一个与从顶部开始的第一个),为什么这些方法从上到下调用的时间也是从最长到最短?
因此,在幕后的原因是,因为首先有一个“热身”过程,其中涉及针对不同操作Stackoverflow link to details
的缓存机制作为解决方案的解决方案:使用BenchmarkDotNet,不要忘记缓存操作(上述操作)