- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
这对我来说是一种耻辱,但我不知道:
You should use clone to copy arrays, because that's generally the fastest way to do it.
正如 Josh Bloch 在此博客中所述:http://www.artima.com/intv/bloch13.html
我一直使用 System.arraycopy(...)
。这两种方法都是 native 的,所以可能没有深入了解库的来源,我无法弄清楚为什么会这样。
我的问题很简单: 为什么它是最快的方式?与区别解释here ,但它没有回答为什么 Josh Bloch 认为 System.arraycopy
有什么区别?clone()
是最快的方法。
最佳答案
我想说明为什么 clone()
是比 System.arraycopy(..)
或其他方法最快的复制数组的方法:
1. clone()
在将源数组复制到目标数组之前不必进行类型检查,如提供的 here .它只是简单地分配新的内存空间并将对象分配给它。另一方面,System.arraycopy(..)
检查类型,然后复制一个数组。
2. clone()
也破坏了优化以消除冗余归零。如您所知,Java 中每个分配的数组都必须使用 0s
或相应的默认值进行初始化。但是,如果 JIT 在创建后立即看到该数组已填充,则可以避免将该数组归零。与使用现有的 0s
或相应的默认值更改副本值相比,这绝对更快。在使用 System.arraycopy(..)
时会花费大量时间来清除和复制已初始化的数组。为此,我执行了一些基准测试。
@BenchmarkMode(Mode.Throughput)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 10, time = 1, batchSize = 1000)
@Measurement(iterations = 10, time = 1, batchSize = 1000)
public class BenchmarkTests {
@Param({"1000","100","10","5", "1"})
private int size;
private int[] original;
@Setup
public void setup() {
original = new int[size];
for (int i = 0; i < size; i++) {
original[i] = i;
}
}
@Benchmark
public int[] SystemArrayCopy() {
final int length = size;
int[] destination = new int[length];
System.arraycopy(original, 0, destination, 0, length);
return destination;
}
@Benchmark
public int[] arrayClone() {
return original.clone();
}
}
输出:
Benchmark (size) Mode Cnt Score Error Units
ArrayCopy.SystemArrayCopy 1 thrpt 10 26324.251 ± 1532.265 ops/s
ArrayCopy.SystemArrayCopy 5 thrpt 10 26435.562 ± 2537.114 ops/s
ArrayCopy.SystemArrayCopy 10 thrpt 10 27262.200 ± 2145.334 ops/s
ArrayCopy.SystemArrayCopy 100 thrpt 10 10524.117 ± 474.325 ops/s
ArrayCopy.SystemArrayCopy 1000 thrpt 10 984.213 ± 121.934 ops/s
ArrayCopy.arrayClone 1 thrpt 10 55832.672 ± 4521.112 ops/s
ArrayCopy.arrayClone 5 thrpt 10 48174.496 ± 2728.928 ops/s
ArrayCopy.arrayClone 10 thrpt 10 46267.482 ± 4641.747 ops/s
ArrayCopy.arrayClone 100 thrpt 10 19837.480 ± 364.156 ops/s
ArrayCopy.arrayClone 1000 thrpt 10 1841.145 ± 110.322 ops/s
根据我得到的输出, clone
几乎是 System.arraycopy(..)
3. 此外,使用像 clone()
这样的手动复制方法会产生更快的输出,因为它不必进行任何 VM 调用(与 System .arraycopy()
).
关于java - 为什么 clone() 是复制数组的最佳方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46145826/
什么是 vb6 或 java 中的对象克隆?我们在什么情况下使用克隆?克隆对象是什么意思?谁能用例子告诉我。 最佳答案 克隆实际上是将对象数据复制到新对象中。 此示例不克隆数据: Foo p = ne
ArrayList a=new ArrayList(); a.add(5); ArrayList b=(ArrayList)a.clone(); a.add(6); System.out.printl
这个问题在这里已经有了答案: Why does cloned() allow this function to compile (1 个回答) 关闭 3 个月前。 假设我们有一个可以克隆的某种类型的
我有这样的代码,我需要在其中将某些内容插入到两个单独的 HashMap 中。我只想要实现克隆的通用类型。 use std::collections::HashMap; use std::clone::
这段代码(also on play) use std::sync::Arc; struct Foo { x: isize, // Something complex in actual cod
我有按钮 Drag to insert h1 tag 当你拖动它时,我希望按钮留在原来的位置,助手是 Example在你放下它的地方,你会放下h1没有任何可拖动或 jQuery UI 样式的标记。 所
覆盖 clone 方法,而不实现 Cloneable 接口(interface)并且不调用 super.clone() 是一个好习惯。这样,就不会抛出 CloneNotSupportedExcepti
public abstract class Shape implements Cloneable { private String id; protected String type;
克隆远程仓库后,它不会通过 -a 选项显示任何远程分支。可能是什么问题呢?如何调试呢?在此片段中,未显示两个远程分支: $ git clone --depth 1 git://git.savannah
我看过这个答案for a git clone error ,建议不要克隆整个 repo,而是只克隆最新的提交,然后使用 unshallow 获取其余的提交。 考虑以下两个命令 1. git clone
当在网上搜索如何以多态方式深层复制对象的可能性时,我发现了 solution声称可以使用 clone() 方法解决许多问题,例如无法克隆 final 字段。该解决方案结合了在 clone() 实现中使
我正在尝试创建一个动态表单来向业务合作伙伴展示。 目标是能够在单击按钮时根据需要添加选择元素。但是,当它被点击时,它会复制模板两次,而不是一次。 这里只是我尝试过的代码的一些变体和 here is t
我知道实现 Object#clone() 的约定表明您应该调用 super.clone() 来获取复制的对象。 但我只是想知道如果我不这样做的话会有什么后果。让我们假设这个例子: class Some
我所说的示例:http://jsfiddle.net/bsnxp/1/ 如果你检查源 .show().clone() display 是 inline-block (它应该是什么)并且 .clone(
我正在编写代码来创建对象、克隆对象,然后比较两者。 所讨论的对象 Octagon 是对象 GeometricObject 的扩展 public class Octagon extends Geomet
我看到clone()在django代码中被广泛使用 queryset.query.clone() queryset.clone() 它的用途是什么?我应该模仿查询集或管理器方法中的行为吗? 最佳答案
我尝试导入 git project进入 eclipse 。手册告诉我在控制台中使用此命令: git clone http://git-wip-us.apache.org/repos/asf/mina-
我正在使用 jquery .clone(),它工作正常。但是我的问题是,当我克隆我的输入字段时,它也会克隆前一个字段的值。我不想克隆该值。我该如何克服这个问题? 这是我的代码 function add
在 this SO thread 中,结果表明,在制作项目副本方面,切片比任何方法都快。 使用: list1 = ['foo','bar'] copy1 = list1 * 1 list1.pop()
我有一个自动脚本可以解析服务器并克隆其中一个文件夹中的所有存储库。它所做的伪代码是: for each repo_name if a folder named like repo_name exi
我是一名优秀的程序员,十分优秀!