慢速运行网格循环创建

时间:2013-08-19 00:03:58

标签: c# .net sql loops

我正在尝试为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");
    }
}

这似乎是一个相当直接的循环.....

3 个答案:

答案 0 :(得分:1)

我猜你的问题是字符串连接。如果不使用分析器测量实际性能,这只是猜测,但我确实看到了问题。

这一行:

 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());

答案 1 :(得分:0)

您可以尝试运行并行线程。现在,代码将运行在单个核心上,并且您可能拥有可以利用的多处理器。将图像分区为块并在其自己的线程中运行每个块。

另外,使用StringBuilder会有所帮助,因为字符串操作非常慢而且你有很多。

答案 2 :(得分:0)

您可能需要查看SqlBulkCopy class

然后你会沿着这些方向做点什么。

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();