4

假设您需要跟踪一个方法被调用的次数,并在它被调用 n 次时打印一些内容。什么是最有效的:

  1. 使用长变量 _counter 并在每次调用该方法时增加它。您测试的每个呼叫是否相等“_counter % n == 0”

  2. 使用 int 变量 _counter 并在每次调用该方法时增加它。当 _counter = n 时,打印消息并将变量 _counter 重置为 0。

有人会说差异可以忽略不计,您可能是对的。我只是好奇什么方法最常用

4

6 回答 6

7

在这种特殊情况下,由于无论如何您都需要一个 if 语句,我会说您应该在达到计数时将其设置为零。

但是,对于您每次都使用该值,并且只想“当我们达到某个值时回绕为零”的情况,那么这种情况就不那么明显了。

如果您可以调整n为 2 的幂(2、4、8、16、32 ...),那么您可以使用与-counter % n相同的技巧,counter & (n-1)这使得操作非常快。

如果n不是 2 的幂,那么您最终可能会进行真正的除法,这是一个坏主意 - 与常规指令相比,除法非常昂贵,并且比较和重置很可能比除法选项更快。

当然,正如其他人所提到的,如果您的计数器达到该类型的 MAX 限制,您最终可能会得到各种乐趣和游戏。

编辑:当然,如果你要打印一些东西,那可能需要比除法长 100 倍的时间,所以它确实是微优化,除非n非常大。

于 2013-02-22T16:00:59.427 回答
1

这取决于 n... 的值,但我敢打赌重置和简单的相等检查会更快。此外,重置计数器更安全,您永远不会达到您的号码的代表限制。编辑:还要考虑可读性,做微优化可能会混淆你的代码。

于 2013-02-22T15:54:12.903 回答
1

为什么不两者都做。

如果它成为一个问题,那么看看它是否值得优化。
但是,在它成为问题之前,即使查看它也是没有意义的(您的算法中会有更大的问题)。

count = (count+1) % countMax;
于 2013-02-22T16:03:53.373 回答
0

检查Guava 的RateLimiter 将使您对类似的实用程序实现有所了解 http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/RateLimiter.html

于 2013-02-22T16:12:16.713 回答
0

我认为,出于以下原因,重置计数器总是更好:

  1. 对于不熟悉的程序员(例如,维护程序员),代码会更清楚。
  2. 重置计数器时,算术(可能是拼写错误)溢出的可能性较小。
于 2013-02-22T15:58:24.863 回答
0

这是 100000000 次迭代的性能时间,以毫秒为单位

模时间 = 1258

计数器时间 = 449

po2Time = 108

正如我们所看到的,2 的幂远远优于其他方法,但它仅适用于 2 的幂,我们的普通计数器也比模数快 2.5 倍。那么我们为什么要使用模数增量呢?嗯,在我看来,我认为它们提供了一个干净的代码,如果使用得当,它们是一个很好的工具来了解

原帖

于 2013-02-22T16:25:15.613 回答