2

我目前正在调查应用程序中的性能问题,并强调了以下内容;

我有一堂课——

public static class CommonIcons
{
    ...
    public static readonly System.Windows.Media.ImageSource Attributes = typeof(CommonIcons).Assembly.GetImageFromResourcePath("Resources/attributes.png");
    ...
}

作为测试工具,然后我使用此类使用以下代码来显示问题 -

for (int loop = 0; loop < 20000; loop++)
{
    // store time before call

    System.Windows.Controls.Image image = new System.Windows.Controls.Image
                    {
                        Source = CommonIcons.Attributes,
                        Width = 16,
                        Height = 16,
                        VerticalAlignment = VerticalAlignment.Center,
                        SnapsToDevicePixels = true
                    };

    // store time after call
    // log time between before and after

}

在循环开始时,时间差小于 0.001 秒,但经过 20000 秒后,时间差增加到 0.015 秒。

如果我不使用静态成员并直接引用我的图标,那么我没有性能影响,即

for (int loop = 0; loop < 20000; loop++)
{
    // store time before call

    System.Windows.Controls.Image image = new System.Windows.Controls.Image
                    {
                        Source = typeof(CommonIcons).Assembly.GetImageFromResourcePath("Resources/attributes.png"),
                        Width = 16,
                        Height = 16,
                        VerticalAlignment = VerticalAlignment.Center,
                        SnapsToDevicePixels = true
                    };

    // store time after call
    // log time between before and after

}

但是在我的真实世界程序中,我不想在每次调用时都创建图像源(在垃圾收集之前增加内存),因此为什么使用静态成员。但是,我也无法忍受性能打击。

有人可以解释为什么原始代码会造成这种性能损失吗?对于我正在尝试做的事情也是一个更好的解决方案?

谢谢

4

3 回答 3

1

它闻起来像是与垃圾收集有关。我想知道在你的第一种情况下是否存在某种耦合ImageSourceImage导致问题。您是否查看过每种情况下测试工具的内存使用情况?

出于兴趣,如果Source在每次迭代结束时将 设置为 null 会发生什么?我知道这有点傻,但这是它作为测试工具的自然推论:) 这可能进一步表明它是源和图像之间的链接......

于 2010-09-23T11:40:43.657 回答
0

区别不在于静态成员与否,而在于在第一个版本中,您创建了 20000 个图像,它们都具有相同的 imagesource。我不知道到底发生了什么,但是在幕后可能会自动创建代理来处理图像源和图像之间的通信,并且每次如果图像源中发生事件,需要通知 20000 个客户端,所以这是一个很大的性能受到打击。

在第二个版本中,20000 个创建的图像中的每一个都有自己的图像,因此您不会遇到这种开销。

请注意,在完成处理后,您应该始终使用它们的 - 方法处理图像等图形对象Dispose(),这将稍微加快您的应用程序并降低您的一般内存使用量。

于 2010-09-23T13:17:50.630 回答
0

你能在你的 CommonIcons 类中只存储像“Resources/attributes.png”这样的常量字符串吗?

于 2010-09-23T11:46:27.093 回答