I wrote a WPF program which is graphical browser of things. It displays quite a lot of images in ListView with Image control for each of them. It also allows user to do basic image editing.
I've run this software on many different machines: my dev laptop, my colleague's MacBook with Paralel Desktop, VirtualBox VM with access via Windows Remote Desktop and even on 10 years old laptop. It run very well.
Unfortunately, our first client is design company with worskstations build for CAD design, with Xeon processors and nVidia Quadro 2000 cards. Now comes the shock: my program is so slow on their machines that it is not usable.
I've used dotTrace and found that the bottleneck is my ImageToImageSourceConverter, which is the most standard one:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Bitmap bmp = value as Bitmap;
if (bmp == null)
return null;
using (MemoryStream memory = new MemoryStream())
{
memory.Seek(0, SeekOrigin.Begin);
bmp.Save(memory, ImageFormat.Bmp);
memory.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
return bitmapImage;
}
dotTrace showed, that on their machines the line with bitmapImage.EndInit() takes the mot of computing time. It is also done on the ui thread so app freezes for a while. dotTrace tells that the call ends up in clr.dll
To show to the scale: on my laptop this conversion tkaes about 5-10ms, depending on bitmap. On their machines (all of them!) it takes around 800ms, or sometimes even more.
On other machines that is not a problem: it runs fast, freezes are not noticable. Even more, displayed bitmaps are so small (200x200px) that when I change this to be async it was slower, due to thread change overhead.
Does someone have any idea why this is happening?
Things I've tried so far:
- disabling hardware rendering via RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; - no difference
- updating the drivers for graphics card: no difference
- disabling all accelerations in graphics card drivers and Window Compability mode: no difference
- running as Administrator (why I did this): it runs noticably faster, but still not enough.
The problem is big: we won't get paid if this will not run faster :D
What is even more weird, sometimes it works just fine for few secconds.
My pen drawing is implemented in such a way, that onMouseMove with button presed I create a copy of previous image and draw additional line with a preview color from last mouse position to the new one and keep track of this points. When you release LMB, I draw the lines between points with target color on original image. It may seem slow, but is suprisingly fast on every machine that I tested.
On theirs, when you click and wait for a moment, then move the mouse it runs smoothly. But when you click and move mouse instantly, it freezes and draws straight line between click position and last position, because it does not register points between.
So, is this related to slow loading some dll and then releasing it when it is not used for some time? If so, which one can it be?
Specs of the workstations: Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz NVIDIA Quadro 2000 1GB 16 GB RAM