本文翻译自:Difference between declaring variables before or in loop?

I have always wondered if, in general, declaring a throw-away variable before a loop, as opposed to repeatedly inside the loop, makes any (performance) difference? 我一直想知道,一般而言,在循环之前声明一个抛弃型变量(而不是在循环内部重复)是否会产生(性能)差异? A (quite pointless) example in Java: Java中的一个(毫无意义的)示例:

a) declaration before loop: a)循环前声明:

double intermediateResult;
for(int i=0; i < 1000; i++){intermediateResult = i;System.out.println(intermediateResult);
}

b) declaration (repeatedly) inside loop: b)循环内的声明(反复):

for(int i=0; i < 1000; i++){double intermediateResult = i;System.out.println(intermediateResult);
}

Which one is better, a or b ? ab哪个更好?

I suspect that repeated variable declaration (example b ) creates more overhead in theory , but that compilers are smart enough so that it doesn't matter. 我怀疑重复的变量声明(示例b ) 在理论上会产生更多开销,但是编译器足够聪明,因此无关紧要。 Example b has the advantage of being more compact and limiting the scope of the variable to where it is used. 示例b的优点是更紧凑,并将变量的范围限制在使用它的地方。 Still, I tend to code according example a . 尽管如此,我还是倾向于根据示例a进行编码。

Edit: I am especially interested in the Java case. 编辑:我对Java案例特别感兴趣。


#1楼

参考:https://stackoom.com/question/1hwd/在循环之前或循环中声明变量之间的区别


#2楼

There is a difference in C# if you are using the variable in a lambda, etc. But in general the compiler will basically do the same thing, assuming the variable is only used within the loop. 如果在lambda等中使用变量,则C#有所不同。但是通常,假定变量仅在循环内使用,编译器基本上会执行相同的操作。

Given that they are basically the same: Note that version b makes it much more obvious to readers that the variable isn't, and can't, be used after the loop. 鉴于它们基本上是相同的:请注意,版本b使读者更清楚地知道该变量在循环之后不能使用,也不能使用。 Additionally, version b is much more easily refactored. 此外, 版本b更易于重构。 It is more difficult to extract the loop body into its own method in version a. 在版本a中将循环体提取到其自己的方法中更加困难。 Moreover, version b assures you that there is no side effect to such a refactoring. 而且,版本b向您保证,这种重构没有副作用。

Hence, version a annoys me to no end, because there's no benefit to it and it makes it much more difficult to reason about the code... 因此,版本a无休止地困扰着我,因为它没有任何好处,并且使推理代码变得更加困难...


#3楼

The following is what I wrote and compiled in .NET. 以下是我在.NET中编写和编译的内容。

double r0;
for (int i = 0; i < 1000; i++) {r0 = i*i;Console.WriteLine(r0);
}for (int j = 0; j < 1000; j++) {double r1 = j*j;Console.WriteLine(r1);
}

This is what I get from .NET Reflector when CIL is rendered back into code. 这是当CIL渲染回代码时从.NET Reflector中获得的。

for (int i = 0; i < 0x3e8; i++)
{double r0 = i * i;Console.WriteLine(r0);
}
for (int j = 0; j < 0x3e8; j++)
{double r1 = j * j;Console.WriteLine(r1);
}

So both look exactly same after compilation. 因此,两者在编译后看起来完全相同。 In managed languages code is converted into CL/byte code and at time of execution it's converted into machine language. 在托管语言中,代码将转换为CL /字节代码,并且在执行时将其转换为机器语言。 So in machine language a double may not even be created on the stack. 因此,在机器语言中,甚至可能不会在堆栈上创建一个double。 It may just be a register as code reflect that it is a temporary variable for WriteLine function. 它可能只是一个寄存器,因为代码反映它是WriteLine函数的临时变量。 There are a whole set optimization rules just for loops. 有整套针对循环的优化规则。 So the average guy shouldn't be worried about it, especially in managed languages. 因此,普通人不必为此担心,尤其是在托管语言中。 There are cases when you can optimize manage code, for example, if you have to concatenate a large number of strings using just string a; a+=anotherstring[i] 在某些情况下,您可以优化管理代码,例如,如果您必须仅使用string a; a+=anotherstring[i]连接大量string a; a+=anotherstring[i] string a; a+=anotherstring[i] vs using StringBuilder . string a; a+=anotherstring[i]与使用StringBuilder There is very big difference in performance between both. 两者之间的性能差异很大。 There are a lot of such cases where the compiler cannot optimize your code, because it cannot figure out what is intended in a bigger scope. 在很多情况下,编译器无法优化您的代码,因为它无法找出更大范围内的目标。 But it can pretty much optimize basic things for you. 但这可以为您优化基本的东西。


#4楼

I've always thought that if you declare your variables inside of your loop then you're wasting memory. 我一直以为,如果在循环内声明变量,那将浪费内存。 If you have something like this: 如果您有这样的事情:

for(;;) {Object o = new Object();
}

Then not only does the object need to be created for each iteration, but there needs to be a new reference allocated for each object. 然后,不仅需要为每个迭代创建对象,而且还需要为每个对象分配一个新的引用。 It seems that if the garbage collector is slow then you'll have a bunch of dangling references that need to be cleaned up. 看来,如果垃圾收集器运行缓慢,那么您将有一堆悬挂的引用需要清理。

However, if you have this: 但是,如果您有:

Object o;
for(;;) {o = new Object();
}

Then you're only creating a single reference and assigning a new object to it each time. 然后,您仅创建一个引用并每次为其分配一个新对象。 Sure, it might take a bit longer for it to go out of scope, but then there's only one dangling reference to deal with. 当然,超出范围可能会花费更长的时间,但是只有一个悬而未决的参考文献需要处理。


#5楼

My practice is following: 我的做法是:

  • if type of variable is simple (int, double, ...) I prefer variant b (inside). 如果变量的类型很简单(int,double,...),我更喜欢变量b (内部)。
    Reason: reducing scope of variable. 原因:减小变量的范围。

  • if type of variable is not simple (some kind of class or struct ) I prefer variant a (outside). 如果变量的类型不简单(某种classstruct ),我更喜欢变体a (外部)。
    Reason: reducing number of ctor-dtor calls. 原因:减少了ctor-dtor调用次数。


#6楼

A) is a safe bet than B).........Imagine if you are initializing structure in loop rather than 'int' or 'float' then what? 与B)相比,A)是一个安全的选择......想象一下,如果您正在循环中初始化结构而不是“ int”或“ float”,那又是什么?

like 喜欢

typedef struct loop_example{JXTZ hi; // where JXTZ could be another type...say closed source lib // you include in Makefile}loop_example_struct;//then....int j = 0; // declare here or face c99 error if in loop - depends on compiler settingfor ( ;j++; )
{loop_example loop_object; // guess the result in memory heap?
}

You are certainly bound to face problems with memory leaks!. 您肯定会遇到内存泄漏的问题!。 Hence I believe 'A' is safer bet while 'B' is vulnerable to memory accumulation esp working close source libraries.You can check usinng 'Valgrind' Tool on Linux specifically sub tool 'Helgrind'. 因此,我相信“ A”是更安全的选择,而“ B”更容易受到内存累积的影响,尤其是在靠近源代码库的情况下。您可以检查Linux上的“ Valgrind”工具,特别是子工具“ Helgrind”。

在循环之前或循环中声明变量之间的区别?相关推荐

  1. 如何在MySQL中声明变量?

    本文翻译自:How to declare a variable in MySQL? How to declare a variable in mysql, so that my second quer ...

  2. postgres 显示变量_sql - 如何在PostgreSQL查询中声明变量

    sql - 如何在PostgreSQL查询中声明变量 如何声明变量以用于PostgreSQL 8.3查询? 在MS SQL Server中,我可以这样做: DECLARE @myvar INT SET ...

  3. python中声明变量注意事项_我们如何在Python中声明变量?

    简短的答案是,无需在Python中声明变量. 以下是更详细的描述. 静态类型语言(C,C ++,Java,C#)要求在程序中使用变量之前,必须先声明要使用的变量的名称和类型声明.相应的语言编译器确保将 ...

  4. python中定义变量和数组_Python中的线程和全局变量 - 数组和标准变量之间的区别?...

    我目前尝试使用线程编写一个更大的python程序,并遇到了数组不必被声明为全局的问题.Python中的线程和全局变量 - 数组和标准变量之间的区别? import numpy as np import ...

  5. java中的成员变量和局部变量的区别_java中成员变量与局部变量区别分析

    本文实例分析了java中成员变量与局部变量区别.分享给大家供大家参考.具体分析如下: 成员变量:在这个类里定义的私有变量,属于这个类. 创建以及使用成员变量 public class Person { ...

  6. ES5和ES6声明变量特性与区别

    在进行javascript详细学习之前,对ES5和ES6的变量声明有个简单的了解,方便我们进行学习理解 变量:存储信息的容器,在ES中变量是松散类型. 松散类型:不对数据类型做限制,前端js的基本数据 ...

  7. c语言中引用头使用什么指令,在源文件(.c)和头文件(.h)中声明和定义的区别——C语言...

    最近在看多文件编程的时候遇到的一个问题,本来以为理解了声明和定义的区别(然而并没有····),也算是重新认识了一次声明和定义,下面上代码 声明和定义:有分配空间的叫定义,没分配空间的叫声明 定义:表示 ...

  8. java中separator_java - File.separator和路径中的斜杠之间的区别

    java - File.separator和路径中的斜杠之间的区别 在Java Path-String中使用/和普通的File.separator有什么区别? 与双反斜杠相比,/平台独立似乎不是原因, ...

  9. for语句中声明变量

    在C语言中,局部变量应该在函数的可执行语句之前定义,但在C++中变量可在任何语句位置定义,只要允许程序语句的地方,都允许定义变量. 在C99标准中C同C++一样允许在for循环语句中定义变量.并且这个 ...

最新文章

  1. 使用Qt D-Bus适配器
  2. 分享轮子-flutter下拉刷新上拉加载
  3. gis影像格式img转为ecw_医学影像图片格式
  4. java 分享巧克力_[leetcode 双周赛 11] 1231 分享巧克力
  5. Octave入门基础
  6. 分布式系统:数据库、操作系统、集群、协调、接口、多处理器、共享、I/O
  7. java图片特效轮播代码_JQuery实现图片轮播效果
  8. FreeNAS存储+iscsi
  9. vagrant 常用的几个命令
  10. Dxg——Arduino 开发笔记整理分类合集【所有的相关记录,都整理在此】
  11. postgresql磁盘空间清理
  12. 深蓝词库转换1.9发布——支持英库拼音、搜狗bin格式、FIT、中州韵等
  13. 咸鱼CAD笔记—CAD快捷键
  14. Matlab函数、子函数的定义方法
  15. Unity入门——实现一个简单的跑酷游戏(资源预制)
  16. SitePoint播客#38:猫的大脑
  17. 选购电脑cpu 酷睿 区别 GPU选择
  18. 机器学习基础、sklearn数据集、转换器与预估器
  19. 机器学习基础:拉格朗日乘子法
  20. jQuery实现点击图片弹出视频并自动播放

热门文章

  1. 山东大学RISC-V公共开放平台开发记录3
  2. ZCU106 裸机NR SHELL移植
  3. 2023北京电子科技大学计算机考研信息汇总
  4. UVA一些简单题题解。
  5. 大学生应该常去的网站
  6. exp00091 oracle,EXP-00091错误的说明和解决方法
  7. 全面深改直面民生“硬骨头” 这些领域获得感满满
  8. 这些活动发布平台你都知道吗?
  9. 计算机保存到桌面没有显示,电脑系统进不去桌面,没有图标怎么办?
  10. iOS开发学无止境 - 6个iOS图片文本设计的小技巧