Java-Big O of bitCount()?
位计数的大O是什么?我不确定该方法是如何工作的,但我假设它是在O(logn)中完成的 特别是对于该代码(其中x=4,y=1):Java-Big O of bitCount()?,java,big-o,bitcount,Java,Big O,Bitcount,位计数的大O是什么?我不确定该方法是如何工作的,但我假设它是在O(logn)中完成的 特别是对于该代码(其中x=4,y=1): 给定它的实现,该方法由六个按顺序执行的O(1)语句组成,因此它是O(1) 它是O(1),下面是它对JDK1.5+的实现: public static int bitCount(int i) { i = i - ((i >>> 1) & 0x55555555); i = (i & 0x33333333) + ((i >
给定它的实现,该方法由六个按顺序执行的O(1)语句组成,因此它是O(1) 它是
O(1)
,下面是它对JDK1.5+的实现:
public static int bitCount(int i) {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
您的
O(log n)
中的n
是什么?整数中的总位数?当谈到大O时,我们将一些任意操作的成本设置为1,可以公平地假设bitCount
的成本为1。实际上,我想象它是O(1)
,例如,在实践中,这个实现没有被使用,因为在大多数平台上Integer.bitCount
和Integer
中的一些其他简单方法,Long
,etc类被实现为JVM内部函数,这通常导致发出单个popcnt
类型指令。仍然O(1):():听起来合理,但你能指出一些源代码使用JVM的内部结构来实现这个(我找到了源代码,它使用了粘贴的代码)?是的,你已经深入研究了JVM的C++源。要查看方法是否是内部化的,请检查JVM版本的,并查找函数名。在本例中,您会发现一行类似于do\u infrant(\u bitCount\u i,java\u lang\u Integer,bitCount\u name,int\u int\u signature,F\u S)
的代码,这表明函数可能是一个内在函数。此时,您必须深入研究.cpp
源代码,以查看它是否确实位于感兴趣的平台上(通常是在.hpp
中找到它之后,但可能不是因为某些原因,例如在特定平台上缺乏支持等)。在位计数
的情况下,它通常会在现代感兴趣的平台上成为一个固有的。另一种方法是在热循环中执行所讨论的方法,然后使用类似perf top
的方法来检查指令正在执行。另请参阅。谢谢,这很有趣。JVM可以自由地以不同于您在JDK源代码中看到的代码的方式实现它,事实上,它是这样做的,因为它是一个“已知函数”。通常它在支持它的平台(大多数有趣的平台)上编译为一条popcnt
指令.并没有真正改变结论(虽然它确实意味着Integer.bitCount()
和Long.bitCount()
通常需要相同的时间-如果查看源代码,这不会是您的结论。
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
public static int bitCount(int i) {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}