Оптимизация кода - C# (200380)
Формулировка задачи:
Добрый вечер, господа! В данный момент я пишу тулзу для демонстрации алгоритмов оценки движения и временной интерполяции и столкнулся со следующей проблемой - программа долго обрабатывает изображения.
Собственно, сам алгоритм рабочий. На С++ дает хорошие результаты за короткое время, но на C# где-то секунду все это делается. Вопрос в том, что можно оптимизировать? Копирование, сравнение, условные операторы? В С++ все было на указателях, здесь тоже стоит прибугнуть к небезопасному коду или есть другие варианты? Жду ваших советов, заранее спасибо.
public unsafe byte[] TimeInterpolation(int count)
{
byte[] current = new byte[Width * Height];
Vector[] vectors = new Vector[Width * Height / 256];
VectorInitialize(vectors, Width * Height / 256);
//данная часть кода прогоняется несколько раз для достижения
//наилучшего эффекта
for (int i = 0; i < count; i++)
{
int W = 16;
int H = 16;
int cnt = 0;
int a = 0, b = 0, min, Nmin, minA = 0, minB = 0;
int dx, dy;
for (int y = 0; y < Height; y += H)
for (int x = 0; x < Width; x += W)
{
min = 16777216;
a = y;
b = x;
//тут происходит "примерка" векторов из предыдущих прогонов
for (int V = 0; V < 8; V++)
{
if (count == 0)
{
if (y == 0 && x == 0)
{
a = y;
b = x;
V = 8;
}
else if (y == 0 && x > 0)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
V = 8;
}
else if (x == Width - W)
{
if (V == 0)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
}
else if (V == 1)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
V = 8;
}
}
else
{
if (V == 0)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
}
else if (V == 1)
{
a = y + vectors[cnt - 21].y;
b = x + vectors[cnt - 21].x;
}
else if (V == 2)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
V = 8;
}
}
}
else
{
if (y == 0 && x == 0)
{
if (V == 0)
{
a = y + vectors[cnt + 1].y;
b = x + vectors[cnt + 1].x;
}
else if (V == 1)
{
a = y + vectors[cnt + 22].y;
b = x + vectors[cnt + 22].x;
}
else if (V == 2)
{
a = y + vectors[cnt + 23].y;
b = x + vectors[cnt + 23].x;
V = 8;
}
}
else if (y == 0 && x > 0 && x < Width - W)
{
if (V == 0)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
}
else if (V == 1)
{
a = y + vectors[cnt + 1].y;
b = x + vectors[cnt + 1].x;
}
else if (V == 2)
{
a = y + vectors[cnt + 21].y;
b = x + vectors[cnt + 21].x;
}
else if (V == 3)
{
a = y + vectors[cnt + 22].y;
b = x + vectors[cnt + 22].x;
}
else if (V == 4)
{
a = y + vectors[cnt + 23].y;
b = x + vectors[cnt + 23].x;
V = 8;
}
}
else if (x == Width - W && y == 0)
{
if (V == 0)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
}
else if (V == 1)
{
a = y + vectors[cnt + 22].y;
b = x + vectors[cnt + 22].x;
}
else if (V == 2)
{
a = y + vectors[cnt + 21].y;
b = x + vectors[cnt + 21].x;
V = 8;
}
}
else if (x == 0 && y < Height - H && y > 0)
{
if (V == 0)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
}
else if (V == 1)
{
a = y + vectors[cnt - 21].y;
b = x + vectors[cnt - 21].x;
}
else if (V == 2)
{
a = y + vectors[cnt + 1].y;
b = x + vectors[cnt + 1].x;
}
else if (V == 3)
{
a = y + vectors[cnt + 22].y;
b = x + vectors[cnt + 22].x;
}
else if (V == 4)
{
a = y + vectors[cnt + 23].y;
b = x + vectors[cnt + 23].x;
V = 8;
}
}
else if (x == 0 && y == Height - H)
{
if (V == 0)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
}
else if (V == 1)
{
a = y + vectors[cnt + 1].y;
b = x + vectors[cnt + 1].x;
}
else if (V == 2)
{
a = y + vectors[cnt - 21].y;
b = x + vectors[cnt - 21].x;
V = 8;
}
}
else if (x == Width - W && y > 0 && y < Height - H)
{
if (V == 0)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
}
else if (V == 1)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
}
else if (V == 2)
{
a = y + vectors[cnt - 23].y;
b = x + vectors[cnt - 23].x;
}
else if (V == 3)
{
a = y + vectors[cnt + 22].y;
b = x + vectors[cnt + 22].x;
}
else if (V == 4)
{
a = y + vectors[cnt + 21].y;
b = x + vectors[cnt + 21].x;
V = 8;
}
}
else if (y == Height - H && x > 0 && x < Width - W)
{
if (V == 0)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
}
else if (V == 1)
{
a = y + vectors[cnt - 21].y;
b = x + vectors[cnt - 21].x;
}
else if (V == 2)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
}
else if (V == 3)
{
a = y + vectors[cnt - 23].y;
b = x + vectors[cnt - 23].x;
}
else if (V == 4)
{
a = y + vectors[cnt + 1].y;
b = x + vectors[cnt + 1].x;
V = 8;
}
}
else if (y == Height - H && x == Width - W)
{
if (V == 0)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
}
else if (V == 1)
{
a = y + vectors[cnt - 23].y;
b = x + vectors[cnt - 23].x;
}
else if (V == 2)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
V = 8;
}
}
else
{
if (V == 0)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
}
else if (V == 1)
{
a = y + vectors[cnt - 21].y;
b = x + vectors[cnt - 21].x;
}
else if (V == 2)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
}
else if (V == 3)
{
a = y + vectors[cnt - 23].y;
b = x + vectors[cnt - 23].x;
}
else if (V == 4)
{
a = y + vectors[cnt + 1].y;
b = x + vectors[cnt + 1].x;
}
else if (V == 5)
{
a = y + vectors[cnt + 21].y;
b = x + vectors[cnt + 21].x;
}
else if (V == 6)
{
a = y + vectors[cnt + 22].y;
b = x + vectors[cnt + 22].x;
}
else if (V == 7)
{
a = y + vectors[cnt + 23].y;
b = x + vectors[cnt + 23].x;
}
}
}
//тут методом градиентного спуска находятся локальные минимумы
//(для нас это будет самым похожим кусочком изображения(макроблоком))
while (true)
{
if (a + H > Height && b + W > Width)
break;
// if (y == 272)
// MessageBox.Show("");
dx = b - x;
dy = a - y;
if (Check(x,y,dx,dy,W))
{
//Nmin = SAD(preview, next, x - dx, y - dy, x + dx, y + dy);
Nmin = 0;
for (int q = 0; q < 16; q++)
for (int z = 0; z < 16; z++)
{
Nmin += Math.Abs(preview[(q + y-dy) * 352 + z + x-dx] -
next[(q + y + dy) * 352 + z + x + dx]);
}
if (min > Nmin)
{
minA = a;
minB = b;
min = Nmin;
}
}
dx = b - x;
dy = a - y + 1;
if (Check(x, y, dx, dy,W))
{
//Nmin = SAD(preview, next, x - dx, y - dy, x + dx, y + dy);
Nmin = 0;
for (int q = 0; q < 16; q++)
for (int z = 0; z < 16; z++)
{
Nmin += Math.Abs(preview[(q + y - dy) * 352 + z + x - dx] -
next[(q + y + dy) * 352 + z + x + dx]);
}
if (min > Nmin)
{
minA = a + 1;
minB = b;
min = Nmin;
}
}
dx = b - x;
dy = a - y - 1;
if (Check(x, y, dx, dy,W))
{
//Nmin = SAD(preview, next, x - dx, y - dy, x + dx, y + dy);
Nmin = 0;
for (int q = 0; q < 16; q++)
for (int z = 0; z < 16; z++)
{
Nmin += Math.Abs(preview[(q + y - dy) * 352 + z + x - dx] -
next[(q + y + dy) * 352 + z + x + dx]);
}
if (min > Nmin)
{
minA = a - 1;
minB = b;
min = Nmin;
}
}
dx = b - x + 1;
dy = a - y;
if (Check(x, y, dx, dy,W))
{
//Nmin = SAD(preview, next, x - dx, y - dy, x + dx, y + dy);
Nmin = 0;
for (int q = 0; q < 16; q++)
for (int z = 0; z < 16; z++)
{
Nmin += Math.Abs(preview[(q + y - dy) * 352 + z + x - dx] -
next[(q + y + dy) * 352 + z + x + dx]);
}
if (min > Nmin)
{
minA = a;
minB = b + 1;
min = Nmin;
}
}
dx = b - x - 1;
dy = a - y;
if (Check(x, y, dx, dy,W))
{
//Nmin = SAD(preview, next, x - dx, y - dy, x + dx, y + dy);
Nmin = 0;
for (int q = 0; q < 16; q++)
for (int z = 0; z < 16; z++)
{
Nmin += Math.Abs(preview[(q + y - dy) * 352 + z + x - dx] -
next[(q + y + dy) * 352 + z + x + dx]);
}
if (min > Nmin)
{
minA = a;
minB = b - 1;
min = Nmin;
}
}
if (a == minA && b == minB)
{
if (vectors[cnt].c > min)
{
vectors[cnt].c = min;
vectors[cnt].x = minB - x;
vectors[cnt].y = minA - y;
//MessageBox.Show(min.ToString());
}
break;
}
else
{
a = minA;
b = minB;
}
}
}
cnt++;
}
}
double tmp;
int c = 0;
for (int i = 0; i < Height; i+=16)
{
for (int j = 0; j < Width; j+=16)
{
for(int q=0;q<16;q++)
for (int z = 0; z < 16; z++)
{
tmp = preview[((i+q) - vectors[c].y) * Width + j + z - vectors[c].x] / 2
+ next[((i+q) + vectors[c].y) * Width + j + z + vectors[c].x] / 2 + .5;
if (tmp > 255)
tmp = 255;
else if (tmp < 0)
tmp = 0;
current[(i+q) * Width + z + j] = (byte)tmp;
}
c++;
}
}
return current;
}Решение задачи: «Оптимизация кода»
textual
Листинг программы
else if (x == Width - W)
{
if (V == 0)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
}
else if (V == 1)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
V = 8;
}
}
else
{
if (V == 0)
{
a = y + vectors[cnt - 1].y;
b = x + vectors[cnt - 1].x;
}
else if (V == 1)
{
a = y + vectors[cnt - 21].y;
b = x + vectors[cnt - 21].x;
}
else if (V == 2)
{
a = y + vectors[cnt - 22].y;
b = x + vectors[cnt - 22].x;
V = 8;
}
}