Java 自动装箱的最大复杂性是什么
我知道我们总是谈论自动装箱时的性能问题,但我想知道这是否会影响算法的大O复杂度 字符类构造函数的Java实现为:Java 自动装箱的最大复杂性是什么,java,algorithm,big-o,Java,Algorithm,Big O,我知道我们总是谈论自动装箱时的性能问题,但我想知道这是否会影响算法的大O复杂度 字符类构造函数的Java实现为: public Character(char value) { this.value = value; } 构造函数是常数时间,因此它实际上归结为对象创建。对象创建会影响大O时间吗?例如,如果您将字符串的字符放入哈希集中,是否仍然是O(n),其中n是字符串中字符的#?简短的答案是否。它不会改变复杂性 在所有情况下,自动装箱单个值的复杂性都是O(1)。向哈希集中添加单个元素的成
public Character(char value) {
this.value = value;
}
构造函数是常数时间,因此它实际上归结为对象创建。对象创建会影响大O时间吗?例如,如果您将
字符串的字符
放入哈希集
中,是否仍然是O(n),其中n是字符串中字符的#?简短的答案是否。它不会改变复杂性
在所有情况下,自动装箱单个值的复杂性都是O(1)
。向哈希集中添加单个元素的成本平均为摊销。同时做这两件事的平均成本仍然是O(1)
向
哈希集添加元素的实际成本是高度可变的。这种可变性是由两方面造成的:
- 由于哈希函数选择不当或“运气不好”导致的哈希冲突会导致
哈希集
搜索长哈希链。在最坏的情况下,这可能是O(N)
。以你为例,这些东西不适用
- 如果
HashSet
中的元素数持续增长,它将定期重新分配其哈希数组并重新创建哈希链。但是,由于HashSet
算法每次将数组大小增加一倍,因此摊销的开销不会改变每次插入的O(1)
平均成本
自动装箱的实际成本也是可变的。对于某些原语,对应的包装器类型为原语值范围的子集维护先前实例化的自动装箱值的缓存。如果valueOf(prim)
给出缓存命中,则不会分配新对象
例如,Character
缓存U0000到U007F的装箱值
有人提到,内存分配的成本不一定是O(1)
。这在技术上是正确的。然而,为了达到比O(1)
更糟糕的行为,你需要一些不好的事情发生;e、 g
- 堆太接近满,导致GC工效学较差
- 使用过多可用物理内存并导致VM抖动的堆
- (在多核系统上)太多线程试图同时访问堆的太多不同区域,导致h/w级内存缓存争用和管道暂停
这些问题的解决方案往往是增加堆大小,购买更多内存,得到一台更强大的机器。。。或者重新设计你的算法
1-最坏情况下的行为是O(N)
仅在哈希函数不好和/或元素模式不好的情况下发生。前者不能用于基本包装器:例如,看看Character::hashCode()
的实现。后者不会发生,因为字符
实现了可比
我不明白装箱或取消装箱为什么会改变复杂性。为什么会这样?装箱是一个固定时间的操作。我希望拆箱便宜,但自动装箱可能很昂贵,因为它要构造一个新对象,所以如果在循环中多次执行,可能会受到严重的惩罚。也就是说,我同意Tim的观点,因为自动装箱/取消装箱都需要固定数量的操作,所以不会影响整个大O。我假设这是一个固定时间的操作,但因为我读到了它的昂贵程度,我想知道为一个涉及自动装箱的算法提供一个解决方案会是什么样子。@markspace我可能误解了你,但在计算复杂性时,“值”是不相关的。O((10^100)n)等于O(n)。