Wydajność si szarpa to tragedia, czy tylko ja nie umiem go efektywnie wykorzystać?

Wydajność si szarpa to tragedia, czy tylko ja nie umiem go efektywnie wykorzystać?

Zadanie: Wskazać w którym miejscu obrazka koncentracja szczegółów jest duża, a w którym mała.
Pomysł na rozwiązanie: Zrobić lekki blur obrazka, a potem policzyć różnicę między oryginałem a rozmytą kopią. Jeszcze wszystko było fajnie, wstępny test na Photoshopie pokazuje, że da się uzyskać całkiem niezłe efekty. Jednak moja implementacja tego w C# jest KOSZMARNIE wolna!

Nie wiem, czy ja robię błąd, czy to po prostu c# jest mało wydajny, ale coś jest nie tak. Skalowanie i pozbawianie koloru obrazka idzie całkiem szybko, natomiast liczenie rozmycia – okropnie wolno.

Zacząłem od wersji takiej, że każdy piksel obrazka jest wczytywany osobno. Było tragicznie. Przepisałem obrazek do tablicy bajtów i na niej liczę wg przekształcenia:

[1,2,1,
2,4,2,
1,2,1]/16

i znów okropnie wolno. Dla wersji z macierzą 5×5 jeszcze gorzej. Zdaję sobie sprawę, że dla marnego obrazka 100×100 to jest 2 600 000 mnożeń i dzieleń oraz trochę przepisywania, ale na Teutatesa! Stary Photoshop na kiepskim sprzęcie liczy rozmycie Gaussa nieporównywalnie szybciej!

Próbowałem wykorzystać do zadania bajerek o nazwie Parallel.For ale zrezygnowałem po oberwaniu wyjątkiem… Pozwoliłoby to policzyć wynik teoretycznie krócej, ale nie szybciej…

Czy rzeczywiście muszę robić hacki typu przemycanie bajtów w longach lub pisać samemu kod wykorzystujący SSE żeby to zrobić szybko? A może zamienić .net na mono i użyć ichniego wsparcia dla SSE? Ostatecznie mógłbym uzyć zewnętrznych bibliotek działających szybko i sprawnie, ale to jest niewskazane, bo chcę się czegoś nauczyć, a nie tylko osiągnąć efekt.
Jeśli trzeba, to z bólem serca porzucę ce kratkę na rzecz ce pe pe, ale bardzo, bardzo niechętnie…

Da się to zrobić szybciej? JAK?