我有一些C#代码用于从磁盘读取图像然后裁剪它们(可选择调整大小)然后保存它们。但看起来在运行期间只使用了30%的CPU,我可以使用多线程来提高速度或磁盘读取速度是瓶颈吗? 如何正确加载CPU和磁盘以获得最佳性能?
string path = args[0];
int counter = 0;
foreach (string dir in Directory.GetDirectories(path))
{
Console.WriteLine("processing: " + dir);
//create folder for faces
string dir_path = dir + "\\face";
System.IO.Directory.CreateDirectory(dir_path);
try
{
string ini_path = dir + "\\.picasa.ini";
if (File.Exists(ini_path))
{
FileIniDataParser parser = new FileIniDataParser();
IniData data = parser.LoadFile(ini_path);
foreach (SectionData section in data.Sections)
{
if (section.SectionName.Contains(".jpg"))
{
string rects = data[section.SectionName]["faces"];
string[] str_rects = GetRectStrings(rects);
for (int i = 0; i < str_rects.Length; ++i)
{
Bitmap img = (Bitmap)Image.FromFile(dir + "\\" + section.SectionName, true);
RectangleF rectF = GetRectangle(str_rects[i]);
int im_w = img.Width;
int im_h = img.Height;
rectF.X = rectF.X * im_w;
rectF.Y = rectF.Y * im_h;
rectF.Width = rectF.Width * im_w;
rectF.Height = rectF.Height * im_h;
Bitmap bmpCrop = img.Clone(rectF, img.PixelFormat);
string text_path = Directory.GetParent(path).FullName + "\\db.txt";
string crop_path = dir + "\\face\\" +
Path.GetFileNameWithoutExtension(dir + "\\" + section.SectionName) + "_" + i.ToString() + "_crop.png";
bool resize = true;
if (resize)
{
Bitmap resized = new Bitmap(bmpCrop, new Size(24, 32));//вынести в параметры
resized.Save(crop_path,
System.Drawing.Imaging.ImageFormat.Png);
Bitmap gr = ConvertGray(resized);
AppendToTxtFile(gr, text_path);
}
else
{
bmpCrop.Save(crop_path,
System.Drawing.Imaging.ImageFormat.Png);
Bitmap gr = ConvertGray(bmpCrop);
AppendToTxtFile(gr, text_path);
}
counter++;
}
}
}
}
}
catch
{
Console.WriteLine("problem in: " + dir);
}
Console.WriteLine("rects: " + counter.ToString());
}
Console.WriteLine("all done");
Console.ReadLine();
答案 0 :(得分:2)
你有两个从磁盘读取的元素,这可能会耗费一些时间,具体取决于你的磁盘质量,但是你仍然受到一般IO工作的限制,并且正在进行CPU限制工作以调整图像大小。
如果您使用.NET 3.5,我建议使用FileStreams.BeginRead(使用较旧的异步模式)异步加载图像,然后启动后台工作程序以处理调整图像大小以最大化CPU的使用。