是否应重用变量以优化资源利用率

本文关键字:优化 资源 利用率 变量 是否 | 更新日期: 2023-09-27 18:20:44

我正在使用Microsoft Visual C#2010。我有几个方法使用大型位图进行本地处理,每个方法都可以调用多次
我可以声明一个全局变量并重用它:

Bitmap workPic, editPic;
...
void Method1() {
    workPic = new Bitmap(editPic);
    ...
}
void Method2() {
    workPic = new Bitmap(editPic.Width * 2, editPic.Height * 2);
    ...
}

或者在每个方法中声明一个局部变量:

Bitmap editPic;
...
void Method1() {
    Bitmap workPic = new Bitmap(editPic);
    ...
}
void Method2() {
    Bitmap workPic = new Bitmap(editPic.Width * 2, editPic.Height * 2);
    ...
}

第二种方法对于代码的清晰度更好(局部变量用于局部使用)。在资源利用率方面有区别吗?

是否应重用变量以优化资源利用率

如果您打算保留分配给您的内存,您可以在方法之后再次使用workPic,您应该将其注册为类变量。如果没有,您可以通过让内存超出范围来释放内存(这总是一个好主意)。

对于管理内存的框架来说,分配一个变量并不重要。只有当您在紧密循环中重新创建一个变量时,您才能通过重用该变量而受益。如果您有基本类型,您甚至可以重用相同的内存。否则,只保留对已分配内存的引用,因此不会从中获得太多好处。

请注意,DisposeworkPic非常重要,因为现在Bitmap后面的非托管内存中存在内存泄漏。最好使用CCD_ 5。

为什么在不必要的情况下应避免全局变量

非局部性--当单个元素的范围受到限制时,源代码最容易理解。全局变量可以是被程序的任何部分读取或修改,使得记住或推理每一种可能的用途。

无访问控制或约束检查--全局变量可以由程序的任何部分获取或设置,以及与它相关的任何规则使用很容易被破坏或遗忘。(换句话说,获取/设置访问器通常比直接数据访问更可取全球数据更是如此。)从广义上讲,缺乏访问在您可能希望运行不受信任的代码(例如使用第三方插件)。

隐式耦合——具有许多全局变量的程序通常在其中一些变量之间具有紧密耦合,并且耦合变量和函数之间。将耦合项分组为内聚项单元通常会带来更好的程序。

并发问题--如果全局变量可以由多个执行线程访问,则同步是必要的(而且过于频繁忽略)。当将模块与全局变量动态链接时组成的系统可能不是线程安全的,即使这两个独立的在数十种不同环境中测试的模块是安全的。

命名空间污染--全局名称随处可见。当您认为正在使用local(拼写错误或忘记声明local)或vice反之亦然。此外,如果您必须将具有相同的全局变量名称,如果幸运的话,您将获得链接错误。如果运气不好,链接器将简单地处理与同一对象同名。

内存分配问题--一些环境具有内存分配方案,用于分配全球性问题棘手。在语言中尤其如此"构造函数"具有分配以外的副作用(因为,在在这种情况下,您可以表达两个全局变量的不安全情况相互依赖)。此外,在动态链接时模块,可能不清楚不同的库是否有自己的全局变量的实例或全局变量是否共享。

测试和限制-使用全局变量的源更难测试,因为无法轻松设置"清理"运行之间的环境。更普遍地说,利用全局任何类型的服务(例如读取和写入文件或数据库)没有明确提供给该源的内容很难测试出于同样的原因。对于通信系统,测试的能力系统不变量可能需要运行多个系统的"副本"同时,任何共享的使用都会极大地阻碍不提供用于共享的服务(包括全局内存)作为测试的一部分。

参考:http://c2.com/cgi/wiki?GlobalVariablesAreBad

这里要理解的主要内容是字段和变量只包含一个引用,内存将分配给"new"创建的对象。因此,在这两种情况下,所有创建的位图对象都需要进行垃圾收集。

不同之处在于,只在方法中引用的对象将在方法执行后立即准备好收集,而在字段中仍有引用的对象只有在包含字段的对象也准备好收集时才准备好收集。

引入字段唯一有意义的情况是,在宿主对象的整个生命周期中重用相同的对象。

在方法开头重新创建对象的情况下,绝对建议使用变量。