在循环内部还是外部声明变量更好?

2024-02-20

最好这样做:

variable1Type foo; 
variable2Type baa; 

foreach(var val in list) 
{
    foo = new Foo( ... ); 
    foo.x = FormatValue(val); 

    baa = new Baa(); 
    baa.main = foo; 
    baa.Do();
}

Or:

foreach(var val in list) 
{
    variable1Type foo = new Foo( ... ); 
    foo.x = FormatValue(val); 

    variable2Type baa = new Baa(); 
    baa.main = foo; 
    baa.Do();
}

问题是:1 case 和 2 case 哪个更快? 差异是否微不足道?实际应用中也是这样吗? 这可能是一个微观优化,但我真的想知道哪个更好。


在性能方面,让我们尝试一下具体的例子:

public void Method1()
{
  foreach(int i in Enumerable.Range(0, 10))
  {
    int x = i * i;
    StringBuilder sb = new StringBuilder();
    sb.Append(x);
    Console.WriteLine(sb);
  }
}
public void Method2()
{
  int x;
  StringBuilder sb;
  foreach(int i in Enumerable.Range(0, 10))
  {
    x = i * i;
    sb = new StringBuilder();
    sb.Append(x);
    Console.WriteLine(sb);
  }
}

我特意选择了值类型和引用类型,以防影响事物。现在,他们的 IL:

.method public hidebysig instance void Method1() cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 i,
        [1] int32 x,
        [2] class [mscorlib]System.Text.StringBuilder sb,
        [3] class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> enumerator)
    L_0000: ldc.i4.0 
    L_0001: ldc.i4.s 10
    L_0003: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32, int32)
    L_0008: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()
    L_000d: stloc.3 
    L_000e: br.s L_002f
    L_0010: ldloc.3 
    L_0011: callvirt instance !0 [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()
    L_0016: stloc.0 
    L_0017: ldloc.0 
    L_0018: ldloc.0 
    L_0019: mul 
    L_001a: stloc.1 
    L_001b: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
    L_0020: stloc.2 
    L_0021: ldloc.2 
    L_0022: ldloc.1 
    L_0023: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(int32)
    L_0028: pop 
    L_0029: ldloc.2 
    L_002a: call void [mscorlib]System.Console::WriteLine(object)
    L_002f: ldloc.3 
    L_0030: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
    L_0035: brtrue.s L_0010
    L_0037: leave.s L_0043
    L_0039: ldloc.3 
    L_003a: brfalse.s L_0042
    L_003c: ldloc.3 
    L_003d: callvirt instance void [mscorlib]System.IDisposable::Dispose()
    L_0042: endfinally 
    L_0043: ret 
    .try L_000e to L_0039 finally handler L_0039 to L_0043
}

.method public hidebysig instance void Method2() cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 x,
        [1] class [mscorlib]System.Text.StringBuilder sb,
        [2] int32 i,
        [3] class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> enumerator)
    L_0000: ldc.i4.0 
    L_0001: ldc.i4.s 10
    L_0003: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32, int32)
    L_0008: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()
    L_000d: stloc.3 
    L_000e: br.s L_002f
    L_0010: ldloc.3 
    L_0011: callvirt instance !0 [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()
    L_0016: stloc.2 
    L_0017: ldloc.2 
    L_0018: ldloc.2 
    L_0019: mul 
    L_001a: stloc.0 
    L_001b: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
    L_0020: stloc.1 
    L_0021: ldloc.1 
    L_0022: ldloc.0 
    L_0023: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(int32)
    L_0028: pop 
    L_0029: ldloc.1 
    L_002a: call void [mscorlib]System.Console::WriteLine(object)
    L_002f: ldloc.3 
    L_0030: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
    L_0035: brtrue.s L_0010
    L_0037: leave.s L_0043
    L_0039: ldloc.3 
    L_003a: brfalse.s L_0042
    L_003c: ldloc.3 
    L_003d: callvirt instance void [mscorlib]System.IDisposable::Dispose()
    L_0042: endfinally 
    L_0043: ret 
    .try L_000e to L_0039 finally handler L_0039 to L_0043
}

正如您所看到的,除了编译器碰巧选择的堆栈顺序(也可能是不同的顺序)之外,它绝对没有任何效果。反过来,实际上没有任何东西是一个人给予抖动以充分利用另一个人没有给予的东西。

除此之外,还有一种差异。

In my Method1(), x and sb范围为foreach,并且不能在其外部有意或无意地访问。

In my Method2(), x and sb在编译时不知道是否可以在foreach(编译器不知道foreach将执行至少一个循环),因此禁止使用它。

到目前为止,没有真正的区别。

I can然而分配和使用x and/or sb之外的foreach。一般来说,我会说,大多数时候这可能是很糟糕的范围界定,所以我倾向于Method1,但我可能有一些合理的理由想要引用它们(更现实的是,如果它们不可能未分配),在这种情况下我会选择Method2.

不过,这只是每个代码如何扩展或不扩展的问题,而不是编写的代码之间的差异。真的,没有什么区别。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在循环内部还是外部声明变量更好? 的相关文章

  • 如何将 C++ 类包装在基于 C 的 dll 或基于 CLI 的 dll 中?

    我被告知将我用 C 编写的类导入到 dll 中 然后在 c 应用程序中使用该 dll 下列的本指南 https stackoverflow com questions 4555961 how to use a class in dll我创建
  • 在 MVC 类上创建主键字段

    我是 MVC 和 C 新手 我只是偶然发现它并发现它很有趣 我遇到了一个不允许我继续的问题 这是我的代码 using System using System Collections Generic using System Linq usi
  • C++ - 模板专业化和部分专业化

    我一直在互联网和 stackoverflow 上寻找具体的答案 但我似乎找不到 我必须创建一个通用类 然后实现特定的功能 我的具体说明是 您需要使用模板表达式参数以及模板类专业化和部分专业化 我有一个模板类 template
  • 为什么 LinkedList 通常比 List 慢?

    我开始在我的一些 C 算法中使用一些 LinkedList 而不是列表 希望能够加快速度 然而 我注意到他们只是感觉更慢 像任何优秀的开发人员一样 我认为我应该尽职调查并验证我的感受 所以我决定对一些简单的循环进行基准测试 我认为用一些随机
  • C++:获取注册表值仅给出第一个字符[重复]

    这个问题在这里已经有答案了 我试图从注册表中获取字符串值 但我只得到第一个字母 HKEY hKey char gamePath MAX PATH if RegOpenKeyEx HKEY CURRENT USER L Software Bl
  • 禁用除滚动之外的 DataGridView

    我如何配置 datagridview 以便用户只能在行中移动并使用滚动 而没有其他 如果我禁用网格不允许我使用滚动 将您的 datagridview 设置为只读 这将禁用任何编辑 dataGridView1 ReadOnly true 在你
  • 将占位符文本添加到文本框

    我正在寻找一种将占位符文本添加到文本框的方法 就像在 html5 中使用文本框一样 IE 如果文本框没有文本 则会添加文本Enter some text here 当用户单击它时 占位符文本消失并允许用户输入自己的文本 如果文本框失去焦点并
  • 未定义异常变量时通过引用捕获

    捕获异常时 标准指导是按值抛出 按引用捕获 据我了解 这有两个原因 如果由于内存不足异常而引发异常 我们将不会调用可能终止程序的复制构造函数 如果异常是继承层次结构的一部分 我们可能会对异常进行对象切片 如果我们有一个场景 我们没有在 ca
  • initializer_list 和默认构造函数重载决策

    include
  • Windows 程序如何临时更改其时区?

    我写了一个函数来返回time t与给定日期的午夜相对应的值 当给定日期没有午夜时 它返回最早可用的时间 例如 当埃及进入夏令时时 这种情况就可能发生 今年 时间更改于 4 月 29 日晚上午夜生效 因此时钟直接从 23 59 转到 01 0
  • 使用 Microsoft Graph 创建用户

    如何使用 Microsoft graph 创建用户 因为我在保存过程中遇到了权限失败的问题 我确实有几个问题 在图中调用创建用户 API 将在哪里创建用户 是在 Azure AD 还是其他地方 我尝试通过传递 json 和必需的标头来调用创
  • 使用对象列表构建树

    我有一个带有属性 id 和parent id 的对象列表 我想建造一棵树来连接那些孩子和父母 1 个父对象可以有多个子对象 并且有一个对象将成为所有对象的祖先 实现该功能最快的算法是什么 我使用 C 作为编程语言 但其他语言也可以 像这样的
  • 使用 cudamalloc()。为什么是双指针?

    我目前正在浏览有关的教程示例http code google com p stanford cs193g sp2010 http code google com p stanford cs193g sp2010 学习CUDA 演示的代码 g
  • 为什么 GCC 6.3 在没有显式 C++11 支持的情况下编译此 Braced-Init-List 代码?

    我有一个问题大括号括起来的列表的不同含义 https stackoverflow com q 37682392 2642059 我知道C 03不支持C 11initializer list 然而 即使没有 std c 11编译器标志 gcc
  • C# - 命名空间内的类型声明

    在命名空间内而不是在类中声明类型的可能用途是什么 For ex namespace Test public delegate void Ispossible 这是有效的并且不会产生任何编译错误 但我无法想象为什么我们会以这种方式声明它而不是
  • 停止 TcpListener 的正确方法

    我目前正在使用 TcpListener 来处理传入连接 每个连接都有一个线程用于处理通信 然后关闭该单个连接 代码如下 TcpListener listener new TcpListener IPAddress Any Port Syst
  • 向每个收件人发送一封包含不同内容的电子邮件(使用抄送字段)

    在你因为这个问题 毫无意义 和 不可能 而驳回之前 请听我说完 问题 我们在使用我们的系统发送的每封电子邮件中实施跟踪像素 即具有唯一 URL 的可下载 GIF 文件 这有助于我们跟踪电子邮件的打开情况 问题是 当我们抄送一些收件人时 跟踪
  • 无效的模板相关成员函数模板推导 - 认为我正在尝试使用 std::set

    我有一个继承自基类模板的类模板 基类模板有一个数据成员和一个成员函数模板 我想从我的超类中调用它 我知道为了消除对成员函数模板的调用的歧义 我必须使用template关键字 我必须明确引用this在超级班里 this gt base mem
  • Crypto++ 和压缩 EC 密钥

    如何在 Crypto 中生成压缩的 ECDSA 密钥 AutoSeededRandomPool prng ECDSA
  • XmlDocument Save 使文件保持打开状态

    我有一个简单的 C 函数 可以创建一个基本的 XML 文件并保存 private void CreateXMlFile string Filename string Name string Company XmlDocument doc n

随机推荐

  • HasResolution 类型类

    我刚刚查了一下HasResolution 类型类 https hackage haskell org package base 4 10 1 0 docs Data Fixed html t HasResolution它有一个单一的方法 r
  • 为什么 .NET 中的多维数组比普通数组慢?

    Edit 我向大家道歉 当我实际上想说 多维数组 时 我使用了术语 锯齿状数组 如下面的示例所示 对于使用了错误的名字 我深表歉意 我实际上发现锯齿状数组比多维数组更快 我已经添加了锯齿状阵列的测量值 I was trying to use
  • 带棱镜的 AutoWirePartialView 不起作用或使用不当?

    我正在尝试使用棱镜7 1AutoWirePartialView绑定一个PartialView到它的 viewModel 但是 绑定不起作用 或者至少将 viewModel 设置为PartialView似乎不起作用 它仍然具有页面的 Bind
  • 当用户编辑字段中的值时,自定义 DatePicker 作为首选项不会保留值

    我创建了一个 DatePickerPreference 即我扩展了 DialogPreference 并在内部创建了一个 DatePicker 对象 并且让它几乎完美地工作 当您单击向上和向下箭头时 它会更改值并保存您选择的值 但是 如果您
  • OpenGL/GLUT 中的鼠标拖动对象[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我一整天都在寻找简单程序的教程或示例代码 单击对象 例如 2D 矩形 然后当您按住并移动鼠标时 对象会跟随鼠标 然后释放鼠标时 对象仍保留
  • 如何在运行时更改语言而不会出现布局问题

    我有一个 winforms 应用程序 用户必须能够在运行时更改语言 为了概括该开关并避免必须对控件名称进行硬编码 我尝试了以下扩展 internal static void SetLanguage this Form form Cultur
  • 如何在 Windows 10 C# 通用应用程序中使用 C++ 类? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想在 Windows 10 C 通用应用程序中执行 cpp 类的方法 由于我是 Windows 应用程序开发和 C 的新手 所以我可
  • 如何使用cmake在android studio中添加外部库?

    我正在尝试使用 cMake 将 live555 so 和 h 文件与 Android 项目链接 如果我不使用绝对路径 则会出现错误 My cMake file cmake minimum required VERSION 3 4 1 inc
  • 使用 jQuery Sortable() 选择多个项目?

    我需要在 jquery 可排序容器中同时拖动多个项目 在本例中 它是应用了 sortable 行为的父 div 内的一系列嵌套 div 有什么建议么 如果您询问是否可以选择多个项目 例如在一个实例中选择 1 3 和 7 在另一个实例中选择
  • 在Django通道中执行数据库查询

    我正在尝试创建一个非常简单的系统 用户为了使用消费者 需要在 WS url 中输入密钥 例如 ws 127 0 0 1 8000 main key KEY 一旦消费者被调用 Django Channels 需要执行一个非常简单的数据库查询来
  • Objective C:如何通过程序从一个选项卡栏切换到另一个选项卡栏

    我的标签栏控制器中有 5 个不同的标签 我的目的是能够通过代码从一个选项卡栏进行切换 例如 我当前位于应用程序的第五个选项卡中 当我单击 完成 按钮时 应用程序应将我的视图切换到属于第一个选项卡的 rootview 控制器 关于我如何做到这
  • SlickGrid 中的额外列

    即使没有垂直滚动条 SlickGrid 始终在标题的最右侧保留一点空间 这个额外的空间看起来就像一个额外的列 我不想要这个额外的空间 我没有找到 SlickGrid 组件的任何公开 API 来删除它 我在里面看到过自动调整列大小 Slick
  • 两个大文件彼此的平行余弦相似度

    我有两个文件 A 和 B A has 400 000 lines each having 50 float values B has 40 000 lines having 50 float values 对于 B 中的每一行 我需要在 A
  • Python:字典列表,如何获取列表中多个项目的特定键的值?

    我有一个字典列表 例如 dict list key1 dict1 value1 key2 dict1 value2 key3 dict1 value3 key1 dict2 value1 key2 dict2 value2 key3 dic
  • 每行创建多边形并保留列

    早上好 下午好或晚上好 我已将一些位置数据分组到 1 小时的分组中 对于每个我都提取了最小的纬度和经度 它看起来像这样 df lt ID time bin count lat lon maxlat minlat maxlon minlon
  • nginx 连接到 .sock 失败(13:权限被拒绝)- 502 错误网关

    我正在使用 nginx uwsgi django 在 centos7 上部署我的第一个站点 它们在测试中单独工作得很好 但我在尝试将它们连接在一起时遇到了 502 bad gateway var log nginx error log 文件
  • D3.js:折线图 - 工具提示和悬停垂直线

    我一直在研究使用 D3 js 构建的交互式折线图 一次悬停时 我希望工具提示以垂直线显示 垂直线效果很好 但是 我遇到了与工具提示相关的问题 工具提示位置不在图表上 我只获取第一个数据元素 这是我的代码 margin top 20 righ
  • 如何减小 iPython 笔记本的文件大小?

    我有一个 IPython 笔记本 虽然里面的代码只有 100 行左右 但它有几兆字节大 我认为它那么大 因为我在里面加载了几张图像 我想将此笔记本添加到 git 存储库 但是 我不想上传那么大的东西 这样很容易再次生成 是否可以仅保存 IP
  • C# 如何反序列化嵌入文本中的 xml 标签?

    我正在尝试使用 XmlSerializer 反序列化 NET 的 XML 文档注释的输出 作为参考 xml 文档的输出如下所示
  • 在循环内部还是外部声明变量更好?

    最好这样做 variable1Type foo variable2Type baa foreach var val in list foo new Foo foo x FormatValue val baa new Baa baa main