2013-08-19 4 views
2

Я пытаюсь создать изображение для синтаксического анализатора SQL, но я столкнулся с проблемой, он начинает работать очень быстро, но со временем он постепенно замедляется, а память продолжает качать от 60 до 300 МБ. Для 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"); 
    } 
} 

Это кажется довольно прямо вперед петлей .....

+1

Я уверен, что у вас есть причины, но в том, что * лучший * способ быть хранения данных изображения? 9 000 000 вставок - это много вставок, которые предположительно являются медленными. Вы посмотрели на создание DataTable и использование указателя пожарного шланга для его вставки (см. SqlBulkCopy)? – Plymouth223

+1

Какие SQL-запросы вы могли бы использовать против этих данных? – David

+0

Мне нужно это для более крупного проекта, над которым я работаю для своей компании. Я не могу говорить о проекте в целом, поскольку он все еще находится в альфа-стадиях и поэтому является довольно конфиденциальным, однако нам действительно нужна эта функция, работающая правильно, поскольку она является основным компонентом. Кто-нибудь может помочь мне решить исходный запрос? – Mattisdada

ответ

0

Вы можете попробовать запустить параллельные потоки. В настоящее время код будет работать на одном ядре, и, возможно, у вас есть несколько процессоров, которыми вы могли бы воспользоваться. Разделите изображение на куски и запустите каждый кусок в своем потоке.

Кроме того, использование StringBuilder поможет в том, что строковые операторы заведомо медленны, и у вас их много.

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

Я собираюсь угадать, что ваша проблема связана с конкатенацией строк. Без измерения фактической производительности с профилировщиком это только предположение, но я вижу проблему.

Эта линия:

sql_data += pixel_to_sql(pix, x, y); 

Строки в .NET неизменны, поэтому при добавлении на строку, он создает совершенно новую строку каждый раз. Итак, для изображения 3000х3000 вы создаете 9 миллионов строковых значений, каждый из которых хранится в памяти (некоторое время).

Используйте StringBuilder вместо этого, как это:

StringBuilder sql_data_builder = new StringBuilder(); 
... 
sql_data_builder.Append(pixel_to_sql(pix, x, y)); 
... 
Console.WriteLine(sql_data_builder.ToString());