这是一段看似非常特殊的C++代码.出于某种奇怪的原因,奇迹般地对数据进行排序使得代码几乎快了六倍.
#include <algorithm>
#include <ctime>
#include <iostream>
int main()
{
// Generate data
const unsigned arraySize = 32768;
int data[arraySize];
for (unsigned c = 0; c < arraySize; ++c)
data[c] = std::rand() % 256;
// !!! With this, the next loop runs faster.
std::sort(data, data + arraySize);
// Test
clock_t start = clock();
long long sum = 0;
for (unsigned i = 0; i < 100000; ++i)
{
// Primary loop
for (unsigned c = 0; c < arraySize; ++c) …Run Code Online (Sandbox Code Playgroud) Bloch中的toArray方法ArrayList使用System.arraycopy和Arrays.copyOf复制数组.
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
Run Code Online (Sandbox Code Playgroud)
如何比较这两种复制方法以及何时应该使用哪种方法?
复制整个数组时,我经常看到人们写道:
int[] dest = new int[orig.length];
System.arraycopy(orig, 0, dest, 0, orig.length);
Run Code Online (Sandbox Code Playgroud)
但在我看来,没有理由支持这一点:
int[] dest = orig.clone();
Run Code Online (Sandbox Code Playgroud)
无论如何,它们都是浅色的.可能这些人只是没有意识到clone存在.那么有什么理由不使用clone?
我想更好地理解当Java编译器遇到如下方法的调用时会发生什么.
<T extends AutoCloseable & Cloneable>
void printType(T... args) {
System.out.println(args.getClass().getComponentType().getSimpleName());
}
// printType() prints "AutoCloseable"
Run Code Online (Sandbox Code Playgroud)
我很清楚,<T extends AutoCloseable & Cloneable>在运行时没有类型,因此编译器可以做出最少的错误,并创建一个类型为两个边界接口之一的数组,丢弃另一个.
无论如何,如果切换接口的顺序,结果仍然是相同的.
<T extends Cloneable & AutoCloseable>
void printType(T... args) {
System.out.println(args.getClass().getComponentType().getSimpleName());
}
// printType() prints "AutoCloseable"
Run Code Online (Sandbox Code Playgroud)
这导致我做了一些调查,看看接口发生变化时会发生什么.在我看来,编译器使用某种严格的顺序规则来决定哪个接口是最重要的,并且接口在代码中出现的顺序不起作用.
<T extends AutoCloseable & Runnable> // "AutoCloseable"
Run Code Online (Sandbox Code Playgroud)
<T extends Runnable & AutoCloseable> // "AutoCloseable"
Run Code Online (Sandbox Code Playgroud)
<T extends AutoCloseable & Serializable> // "Serializable"
Run Code Online (Sandbox Code Playgroud)
<T extends Serializable & AutoCloseable> // "Serializable"
Run Code Online (Sandbox Code Playgroud)
<T extends SafeVarargs & Serializable> // "SafeVarargs"
Run Code Online (Sandbox Code Playgroud)
<T extends Serializable …Run Code Online (Sandbox Code Playgroud) 我正在玩JMH(http://openjdk.java.net/projects/code-tools/jmh/),我偶然发现了一个奇怪的结果.
我正在对数组的浅层副本进行基准测试,我可以观察到预期的结果(循环遍历数组是一个坏主意#clone(),System#arraycopy()并且在Arrays#copyOf()性能方面没有显着差异).
除了System#arraycopy()是一个季度的慢时,数组的长度是硬编码的......等等,什么?这怎么会慢?
有没有人知道可能是什么原因?
结果(吞吐量):
# JMH 1.11 (released 17 days ago)
# VM version: JDK 1.8.0_05, VM 25.5-b02
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8 -Duser.country=FR -Duser.language=fr -Duser.variant
# Warmup: 20 iterations, 1 s each
# Measurement: 20 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
Benchmark Mode Cnt Score Error Units
ArrayCopyBenchmark.ArraysCopyOf thrpt …Run Code Online (Sandbox Code Playgroud) java ×6
arrays ×3
performance ×2
c++ ×1
clone ×1
cloneable ×1
deprecated ×1
java-8 ×1
jls ×1
jmh ×1
optimization ×1