创建运行缓慢的网格循环
本文关键字:网格 循环 缓慢 运行 创建 | 更新日期: 2023-09-27 18:28:12
我正试图创建一个映像到SQL解析器,但遇到了一个障碍,它一开始运行得很快,但随着时间的推移,它逐渐变慢,内存在60MB和300MB之间徘徊。对于3000x3000的图像,需要16个多小时。。。。。。
class Img2Sql
{
static string table_name="test";
static string sql_data="";
public void Start()
{
Console.Write("Enter in a full path to file: ");
String file_full_path = Console.ReadLine();
Bitmap image = AForge.Imaging.Image.FromFile(file_full_path);
Console.WriteLine("Loaded image from File.... {0}'n", file_full_path);
int x = 0;
int y = 0;
int grid_x = image.Width;
int grid_y = image.Height;
Color pix;
for (y = 0; y < grid_y; y++)
{
for (x = 0; x < grid_x; x++)
{
Console.WriteLine("({0},{1})",x,y);
pix = image.GetPixel(x, y);
sql_data += pixel_to_sql(pix, x, y);
//process_slow_destory_max_min(ref pix, ref img, x, y);
}
}
Console.WriteLine(sql_data);
}
static string pixel_to_sql(Color pix,int x,int y)
{
return ("INSERT INTO "+table_name+"(red,green,blue,x,y) VALUES("+pix.R+","+pix.G+","+pix.B+","+x+","+y+");'n");
}
}
这似乎是一个相当直接的循环。。。。。
我猜您的问题是字符串串联。如果不使用探查器来衡量实际性能,这只是一个猜测,但我确实看到了一个问题。
此行:
sql_data += pixel_to_sql(pix, x, y);
.NET中的字符串是不可变的,所以当你添加到一个字符串中时,它每次都会创建一个全新的字符串。因此,对于3000x3000的图像,您将创建900万个字符串值,每个值都存储在内存中(一段时间)。
改为使用StringBuilder
,如下所示:
StringBuilder sql_data_builder = new StringBuilder();
...
sql_data_builder.Append(pixel_to_sql(pix, x, y));
...
Console.WriteLine(sql_data_builder.ToString());
您可以尝试运行并行线程。目前的情况是,代码将在单核上运行,并且可能有一个可以利用的多处理器。将图像划分为块,并在其自己的线程中运行每个块。
此外,使用StringBuilder也会有所帮助,因为字符串操作是出了名的慢,而且你有很多这样的操作。
您可能需要查看SqlBulkCopy类。
然后你会沿着这些路线做一些事情。
Color pix;
var myList = new List<myPixel>();
for (y = 0; y < grid_y; y++)
{
for (x = 0; x < grid_x; x++)
{
Console.WriteLine("({0},{1})",x,y);
pix = image.GetPixel(x, y);
myPixels.Add(new myPixel() { Pixel = pix, X = x, Y = y});
}
}
var dataTable = //convert your object to a datatable
dbConnection.Open();
//Save to SqlServer
var bulkCopy = new SqlBulkCopy(dbConnection) { DestinationTableName = "YourDatabaseTableName"};
bulkCopy.WriteToServer(dataTable);
dbConnection.Close();