Java快捷方式:生成数组将for循环改为for-each循环
我考虑过在我的竞赛编程中使用这个快捷方式。我定义了一个函数:
private static int[] range(int n) {
int[] ret = new int[n];
for (int i = 0; i < n; i++) {
ret[i] = i;
}
return ret;
}
这样我就可以更快地编写 for 循环,并且看起来更整洁(扫描代码时):
for (int i: range(n)) { doit(i); }
而不是:
for (int i = 0; i < n; i++) { doit(i); }
这种方法是否存在任何重大性能问题,它们是什么?
代码计算解决方案有时间限制,但使用正确的算法通常可以在时间限制的一小部分内完成此操作。 range 函数的运行时间复杂度为 O(n),并且因为无论如何我们都将运行 O(n) 循环,所以时间复杂度不会增加。那么垃圾收集呢?还有什么我没有想到的吗?
稍后我将确定我是否真的喜欢使用此方法,以及是否值得在比赛开始时输入函数的开销。 请不要回答有关风格的问题。(竞争编码会产生一些您见过的最糟糕的代码,但这一切都是为了按时完成并且永远不要再看它。
)澄清一下,实际编码时间在本次比赛中至关重要,我们不能携带预先输入的代码。这通常也意味着没有代码片段。在匆忙而混乱的编码环境中,foreach
将使 for 循环的输入速度更快,并且不易出错。它是 C++ 中宏的替代方案。
I have considered using this shortcut in my competition programming. I define a function:
private static int[] range(int n) {
int[] ret = new int[n];
for (int i = 0; i < n; i++) {
ret[i] = i;
}
return ret;
}
so that I can write my for loops slightly quicker, and slightly neater looking (when scanning code):
for (int i: range(n)) { doit(i); }
instead of:
for (int i = 0; i < n; i++) { doit(i); }
Are there any significant performance issues with this approach and what are they?
The code has a time limit to calculate a solution, but using the right algorithm it's usually possible to do this in a fraction of the time limit. The range function runs in O(n) and because we are going to run a O(n) loop anyway, there is no increase in time complexity. What about garbage collection? Anything else I'm not thinking of?
I will determine if I actually like using this method later, and if it's worth the overhead of typing out the functions at the start of the competition. Please don't answer about the style. (Competition coding produces some of the worst looking code you've ever seen, but it's all about getting it done on time and never looking at it again.)
To clarify, actual coding time is crucial in this competition and we can't bring pre-typed code. This generally means no code snippets either. The foreach
will make for loops quicker to type, and less error prone, in the rushed and messy coding environment. It is an alternative to macros in C++.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在这种情况下,我更愿意这样做。
在我看来,将其转换为数组并没有真正带来任何好处。在这里,性能对我来说并不是太重要,也许只是其次。首先,我不这样做,因为它是为了再编写一个方法,而这并没有提供太多东西。此外,为什么要执行 2 个循环,而只需执行 1 个循环就足够了。
如果您要编写许多
for 循环
,那么foreach
循环可能并不适合所有情况,您最终可能会使用传统的for 循环
code>,无论如何,也许大多数时候。你必须考虑我们在编程竞赛中通常遇到的问题。您可能需要循环中的index
来进行一些计算。谁知道呢。此外,在foreach
进入 Java 之前,我发现自己提出for-loop
的速度并不慢。此外,在比赛中我们通常不关心表现,除非明确提到。如果是这样,您的解决方法将不会被非常积极地采用。
I would prefer to do it this way, in this kinda situation.
Converting it to an array is not really giving any benefit, IMO. Performance is not much of a concern for me here, may be it will be but second. First, I don't do that because its about writing one more method, which is giving nothing much. Moreover, why execute 2 loops when just 1 would have been sufficient.
In case you will write many many
for-loops
, thenforeach
loop might not be suitable for every situation and you might end up using traditionalfor-loop
, anyway, perhaps most of the time. You must consider the problems we usually get in programming competition. You might need theindex
in the loop to do some calculation. Who knows. Further, I didn't find myself not too slow in coming up withfor-loop
beforeforeach
came into Java.Moreover, in competition we usually we don't care about performance, unless its mentioned explicitly. And if it is, your workaround would not be taken very positively.
我建议使用:
for (int i = 0; i < n; i++) { doit(i); }
如果您正在寻找快速的执行时间。
其他方法将在为 i 赋值时执行数组查找和复制值消耗时间。
我尝试运行快速测试来验证:
获得的结果是:
I would suggest use of:
for (int i = 0; i < n; i++) { doit(i); }
if you are looking for fast execution time.
Other approach will consume time in performing array look-up and copying values when assigning value to i.
I tried to run a quick test to verify:
The result obtained is:
对于小型阵列,这不会是问题(如果不确定,您可以对其进行基准测试)。
哪里有更好的方法来做同样的事情。 Foreach 循环可以迭代 Iterable 实例。您可以创建类 RangeIterable 实现 Iterable,并创建静态方法 RangeIterable range(int from, int to),就像您所做的那样。它会更加面向对象编程(OOP)方式,并且在内存方面更容易。对于 [-127,128] 内的范围,甚至整数装箱也不会成为问题,这是预缓存 Integer 实例的默认范围
For small array it will not be an issue (you may just benchmark it if you not sure).
Where is better way to do same thing. Foreach loop can iterate over Iterable instances. You can ccreate class RangeIterable implements Iterable, and make static method RangeIterable range(int from, int to), like you do. It'll be a little more OOP-way, and it's cheeper in terms of memory. And even integer boxing will not be an issue for ranges inside [-127,128], which is default range for precach Integer instances
我不认为创建数组会提高性能。
您可能还想看看这个:
过早优化是万恶之源
I don't think that creating an array will improve the performace.
You also might want to look at this:
Premature optimization is the root of all evil