【问题标题】:Complexity of enum.values()enum.values() 的复杂性
【发布时间】:2014-11-23 13:26:11
【问题描述】:

我有一个非常简单的枚举如下:

public enum Colour { RED, BLUE, GREEN; }

这里我放了三种颜色,但它可能有一个undefined尺寸。

这个 Enum 将用于一个可以有 undefined 个实例(数百、数千甚至数百万)的类。

在这个类中,我有一个必须返回随机颜色的方法。

对此我有两种选择。

private Colour[] colours;

public Datastructure() {

    colours = Colour.values();
}

public Colour getRandomColour() {
     return colours[rand.nextInt() % colours.length];
}

或者我可以继续调用 Colour.values() 而不是创建颜色列表。

public Colour getRandromColour() {
     return Colour.values()[rand.nexInt() % Colour.values().length]

在第一个选项中,创建了一个额外的数组。请记住,此类可能有很多实例,因此可能会被视为浪费内存,并且可能还会影响运行时间(实例化数组)。尤其是当有很多类实例时。

在第二个选项中, Colour.values() 被调用了几次(在这个简单的例子中它只有几次,但在我的项目中它有点复杂并且有更多的调用)所以这可以被认为是浪费CPU 使用率。

我更喜欢使用第二个选项,但我很好奇 Colour.values() 方法的复杂性,我担心它可能是线性 O(n)。 n 是枚举中颜色的数量。当有很多颜色时,这将是可怕的。

还是只是权衡取舍,取其二?

tl;dr Enum.values() 的复杂度是多少?

【问题讨论】:

  • 你在浪费时间尝试对完全不相关的东西进行微优化。
  • @BoristheSpider 解释一下?
  • 取模是一项昂贵的操作。你最好打电话给rand.nextInt(values().length)
  • 如果你关心微优化,你应该使用c++。
  • @Auberon 然后考虑this link,它将给出枚举元素的最大数量为 65535。

标签: java enums complexity-theory


【解决方案1】:

Colour.values() 返回的数组总是包含相同的元素,但是values() 每次调用它都会创建一个 new 数组(所以它是 O(n),其中 n 是枚举值的数量)。而且您永远不会修改该数组。因此,每次需要时调用该方法都是浪费时间。在 DataStructure 类的每个实例中存储一个数组是浪费时间和内存。我只需调用该方法一次并将该数组缓存在一个常量中:

private static final Colour[] COLOURS = colour.values();

public Colour getRandomColour() {
    return COLOURS[rand.nextInt(COLOURS.length)];
}

只要确保这个数组永远不会暴露在类之外。

还要注意 Random.nextInt(limit) 的用法,它完全符合您的要求,可能更快,并且比使用模数更清楚地表达了意图。

【讨论】:

  • 谢谢。有点奇怪,我没有想到这一点。您能否修改您的答案,使其提及@BoristheSpider 指出的内容? (取模很昂贵 + .values() 与 .clone() 等价,即 O(n))
  • @Auberon 回答已修改。
  • 就我个人而言,我会在枚举类本身内完成所有这些工作(将 randCOLORS 定义为其私有静态成员,将 getRandomColour 定义为公共静态成员)。保持Colour相关函数封装在Colour中。
  • @RealSkeptic 这当然是一个有效的选择。这主要取决于您如何看待getRandomColour():它是一种普遍有用且许多类需要调用的方法,还是仅在特定用例中有用且不应污染公众的方法枚举的 API?
【解决方案2】:

为什么不把缓存的数组放在 Color 枚举本身的静态字段中。然后在 Color 枚举中提供一个方法来返回一个随机条目。

无论如何,Color 枚举拥有这段数据/方法是有意义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-18
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多