111,094
社区成员




int width = 1920;
int height = 1200;
byte[] sortnewGrey = new byte[width * height];
int sortlistCount=400;
Parallel.For(0, sortnewGrey.Length, (i) => //sortnewGrey.Length, (i) =>
// for (int i = 0; i <100; i++)
{
lock (obj)
{
byte[] data = new byte[sortlistCount];
int num = 0;
//这部分耗时30几s 屏蔽掉的情况下耗时1s
//foreach (var item in sortlist.Values)
//{
// data[num++] = item[i];
//}
sortnewGrey[i] = data.Max() ;
}
});
SortedList<double, byte[]> sortlist = new SortedList<double, byte[]>();
Parallel.ForEach(arrFileNames, name =>
{
lock (obj)
{
using (img = (Bitmap)Bitmap.FromFile(name))
{
double nameIndex = Convert.ToDouble(Path.GetFileNameWithoutExtension(name));
sortlist.Add(nameIndex, ToArray(img));
}
}
});
这是外面部分的 不在我stopwatch测试时间范围内。现在是需要每次循环都取每个图片相同位置上的像素值作为这个data数组因此 我需要每次循环都遍历它
byte[] data;
for(int I=0;i<sortnewGrey.Length;i++)
{
data = new byte[sortlistCount];
int num = 0;
//这部分耗时30几s 屏蔽掉的情况下耗时1s
//foreach (var item in sortlist.Values)
//{
// data[num++] = item[i];
//}
sortnewGrey[i] = data.Max() ;
}
这样,应该是较快的,lz自己用System.Diagnostics.Stopwatch测试下。static object obj = new object();
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
int width = 1920;
int height = 1200;
byte[] sortnewGrey = new byte[width * height];
int sortlistCount = 400;
//并行处理 (取消 lock)
Parallel.For(0, sortnewGrey.Length, (i) => //sortnewGrey.Length, (i) =>
// for (int i = 0; i <100; i++)
{
//lock (obj)
{
byte[] data = new byte[sortlistCount];
int num = 0;
//这部分耗时30几s 屏蔽掉的情况下耗时1s
//foreach (var item in sortlist.Values)
//{
// data[num++] = item[i];
//}
sortnewGrey[i] = data.Max();
}
});
Console.WriteLine("Parallel nolock:"+ sw.ElapsedMilliseconds);
sw.Restart();
//并行处理 (开启lock)
Parallel.For(0, sortnewGrey.Length, (i) => //sortnewGrey.Length, (i) =>
// for (int i = 0; i <100; i++)
{
lock (obj)
{
byte[] data = new byte[sortlistCount];
int num = 0;
//这部分耗时30几s 屏蔽掉的情况下耗时1s
//foreach (var item in sortlist.Values)
//{
// data[num++] = item[i];
//}
sortnewGrey[i] = data.Max();
}
});
Console.WriteLine("Parallel lock:" + sw.ElapsedMilliseconds);
sw.Restart();
//普通循环(取消 lock)
for (int i = 0; i < sortnewGrey.Length; i++)
{
byte[] data = new byte[sortlistCount];
int num = 0;
//这部分耗时30几s 屏蔽掉的情况下耗时1s
//foreach (var item in sortlist.Values)
//{
// data[num++] = item[i];
//}
sortnewGrey[i] = data.Max();
}
Console.WriteLine("For nolock:" + sw.ElapsedMilliseconds);
sw.Restart();
//普通循环(开启 lock)
for (int i = 0; i < sortnewGrey.Length; i++)
{
lock (obj)
{
byte[] data = new byte[sortlistCount];
int num = 0;
//这部分耗时30几s 屏蔽掉的情况下耗时1s
//foreach (var item in sortlist.Values)
//{
// data[num++] = item[i];
//}
sortnewGrey[i] = data.Max();
}
}
sw.Stop();
Console.WriteLine("For lock:" + sw.ElapsedMilliseconds);
Console.ReadLine();
}
lock (obj)
{
byte[] data = new byte[sortlistCount];
int num = 0;
//这部分耗时30几s 屏蔽掉的情况下耗时1s
//foreach (var item in sortlist.Values)
//{
// data[num++] = item[i];
//}
sortnewGrey[i] = data.Max() ;
}
应写作
byte[] data = new byte[sortlistCount];
int num = 0;
//这部分耗时30几s 屏蔽掉的情况下耗时1s
//foreach (var item in sortlist.Values)
//{
// data[num++] = item[i];
//}
lock (obj)
{
sortnewGrey[i] = data.Max() ;
}
data 是临时变量,不会产生共享冲突。不应将费事操放在 lock 段中
没有看到 sortlist 是如何赋值的,不知道是否有必要每次循环都遍历他(显然你示例的代码是经过裁剪的)
如果有可能,应先对 sortlist 的数据源做预处理
从代码上看 sortlist.Values 是一个二维结构,可能先做一下行列转置,要好一些
int width = 1920;
int height = 1200;
byte[] sortnewGrey = new byte[width * height];
int sortlistCount=400;
byte[] data = new byte[sortlistCount];
int num = 0;
Parallel.For(0, sortnewGrey.Length, (i) => //sortnewGrey.Length, (i) =>
// for (int i = 0; i <100; i++)
{
lock (obj)
{
num = 0;
//这部分耗时30几s 屏蔽掉的情况下耗时1s
foreach (var item in sortlist.Values)
{
data[num] = item[i];
MaxNum = data[num] > MaxNum ? data[num]:MaxNum;
num++;
}
sortnewGrey[i] = MaxNum ;
}
});