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

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(使用前将#替换为@)

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

  • 使用 JSON 格式正确配置 NLog 到 IHostBuilder

    我有以下代码 应该接受 NLog 的 JSON appsettings 配置 然后使用它来创建 NLog LogFactory 这个 NLog 工厂应该被传递到 MyService 类中 以便在那里创建一个记录器 class Program
  • 每次调用新方法时触发事件

    我正在做一个logger for a c 应用程序需要记录每个方法被调用的时间以及每个方法执行时间 我可以通过调用自己的方法来做到这一点EventLogger LogMethodCall方法在每个方法的开头 但我想知道是否有办法使CLR每次
  • 如何启动异步任务对象

    我想开始收集Task同时处理对象并等待所有对象完成 下面的代码显示了我想要的行为 public class Program class TaskTest private Task createPauseTask int ms works w
  • 宏可以按参数数量重载吗?

    如何this https stackoverflow com q 9183993 153285工作 如何实现 C99 C 11 可变参数宏以仅根据为其提供多少个参数来扩展到不同的事物 编辑 请参阅末尾以获得现成的解决方案 要获得重载的宏 首
  • 在不使用 ncurses 的情况下用 C/C++ 编写“真正的”交互式终端程序,例如 vim、htop...

    不 我不想使用ncurses 因为我想了解如何 终端可以工作 并且我自己编程也很有趣 没有 必须是可移植的 它必须只能在基于 linux xterm 的终端仿真器上工作 我想做的是编写一个交互式终端应用程序 例如 htop 和 vim 我的
  • 使用 size_t 值反向遍历向量

    我想以相反的方向遍历向量的值 如您所知 向量的大小为 size t 当我使用以下代码时 for size t r m size 1 r gt 0 r x r f r for size t c r 1 c lt m size c x r m
  • 读取STM32 MCU SPI数据寄存器的值

    有很多类似的问题 但似乎没有一个问题完全相同 我正在将 STML4 MCU 连接到 6 轴传感器 LSM6DS3 我已经成功地在 I2C 中实现了所有内容 但想要 SPI 的额外速度 和 DMA 如果我能让这些第一步工作起来的话 因此 第一
  • C++:初始化静态字符串成员

    我在 C 中初始化静态字符串成员时遇到一些问题 我有几个类 每个类都包含几个表示 id 的静态字符串成员 当我通过调用静态函数初始化变量时 一切都很好 但是 当我想为一个变量分配另一个变量的值时 它仍然保留空字符串 这段代码有什么问题 st
  • 函数参数评估顺序[重复]

    这个问题在这里已经有答案了 在 C 和 C 中 函数参数的求值是否有固定的顺序 我的意思是 标准怎么说 是吗left to right or right to left 我从书中得到的信息令人困惑 是否有必要function call应该使
  • 使用 INotifyPropertyChanged

    有人可以解释一下为什么在 wpf 中使用绑定时需要使用 INotifyPropertyChanged 的 实现吗 我可以在不实现此接口的情况下绑定属性吗 例如我有代码 public class StudentData INotifyProp
  • DotNET 应用程序中的 GDI 句柄

    我的纯 DotNET 库作为非托管桌面应用程序中的插件运行 我收到了稳定的 虽然低 崩溃报告流 这些报告似乎表明 GDI 句柄存在问题 错误消息中的字体等 恢复为系统字体 各种控件的显示崩溃 不久后发生大规模崩溃 我的窗体几乎没有控件 但我
  • 非静态类中的静态方法和静态类中的静态方法有什么区别?

    我有两个班级A级和B级 static class ClassA static string SomeMethod return I am a Static Method class ClassB static string SomeMeth
  • EWS - 给予预约,获取预约的所有者副本

    在 EWS 中进行预约后 是否可以获得所有者的副本 例如 如果我登录为user1 我有user1创建的约会的副本user2 我有冒充权 我要编辑user2预约的副本 我怎样才能获得user2 s copy 您可以使用 PidLidClean
  • C# Julian 日期解析器

    我在电子表格中有一个单元格 它是 Excel 中的日期对象 但当它来自 C1 的 xls 类时 它会变成双精度型 类似于 2009 年 1 月 7 日的 39820 0 我读到这是儒略日期格式 有人可以告诉我如何在 C 中将其解析回 Dat
  • 字符串 c 的二叉树

    我正在尝试实现一个能够在 c 中保存字符串的二叉树 在让代码适用于整数之后 我尝试稍微修改它以处理字符数组 现在我似乎完全破解了代码 但不知道如何破解 任何帮助表示赞赏 include
  • 修改代码以从 Windows 中的 PE 可执行文件检索双重签名信息?

    我已经挣扎了一段时间想要修改这段代码示例 https support microsoft com en us help 323809 how to get information from authenticode signed execu
  • 未找到 _sqlite3_open 等符号错误

    您好 我收到此错误 Undefined symbols sqlite3 open referenced from main in ccRlWVer o sqliite3 close referenced from main in ccRlW
  • 如何在 C# 中以编程方式创建柔和的颜色?

    根据所需的颜色数量均匀分布地生成它们 如果指定的计数为 8 则看起来像这样 List
  • Java有没有类似微软CHESS的工具?

    是否有类似于 Microsoft 的现有 Java 工具CHESS http research microsoft com chess 或者 CHESS 源代码是否开放 以便我可以尝试将其转换为 Java 谷歌的织线工 http code
  • 扔掉挥发物安全吗?

    大多数时候 我都是这样做的 class a public a i 100 OK delete int j Compiler happy But is it safe The following code will lead compilat

随机推荐

  • 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