Tag: 性能

是否有可能使java.lang.invoke.MethodHandle与直接调用一样快?

我正在比较MethodHandle::invoke和直接静态方法MethodHandle::invoke性能。 这是静态方法: public class IntSum { public static int sum(int a, int b){ return a + b; } } 这是我的基准: @State(Scope.Benchmark) public class MyBenchmark { public int first; public int second; public final MethodHandle mhh; @Benchmark @OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public int directMethodCall() { return IntSum.sum(first, second); } @Benchmark @OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) public int finalMethodHandle() throws Throwable { […]

Java循环效率

我正在比较Java中嵌套for,while和do-while循环的效率,并且我遇到了一些我需要帮助理解的奇怪结果。 public class Loops { public static void main(String[] args) { int L = 100000; // number of iterations per loop // for loop double start = System.currentTimeMillis(); long s1 = 0; for (int i=0; i < L; i++) { for (int j = 0; j < L; j++) { s1 += 1; } } […]

处理时间措施的最佳方法是什么?

我的目标是编写一个框架,用于测量方法执行或事务时间以及处理测量,即存储,分析等。事务可能包括调用外部系统,同步或异步等待结果。 关于这个话题已经存在一些问题,比如 “ 我如何计算方法的执行时间 ” “ 测量Java方法的执行时间 ” “ System.currentTimeMillis vs System.nanoTime ” 所有的答案归结为三种方法来花时间 System.currentTimeMillis() System.nanoTime() Instant.now()和Duration (自Java 8起) 我知道,所有这些都有一些影响 System.currentTimeMillis的() 此方法的结果取决于平台。 在Linux上你获得1ms的分辨率,在Windows中你可以获得10ms(单核)~15ms(多核)。 因此,可以测量大型运行操作或短期运行操作的多次执行。 System.nanoTime() 你获得了一个高分辨率的时间测量,具有纳秒精度(但不一定是纳秒精度),并且在292年后你会得到溢出(我可以忍受)。 Instant.now()和持续时间 从Java 8开始,有新的时间API。 瞬间有第二个和第二个纳米字段,因此它在对象引用的顶部使用两个长值( Duration相同)。 您还可以获得纳秒级精度,具体取决于基础时钟(请参阅“ 具有纳秒分辨率的Java 8 Instant.now()? ”)。 实例化是通过调用Instant.now()完成的, Instant.now()映射到System.currentTimeMillis()以获得正常的系统时钟。 鉴于事实,很明显,最佳精确度只能通过System.nanoTime()实现,但我的问题更多地针对处理一般措施的最佳实践 ,其中不仅包括采取措施,还包括措施处理。 Instant和Duration提供最佳API支持(计算,比较等),但在标准情况下具有os-dependend精度,内存和创建度量的更多开销(对象构造,更深的callstack) System.nanoTime()和System.currentTimeMillis()具有不同的精度级别,但只有基本的“api”支持(长时间的数学运算),但更快和更小以保持在内存中。 那么最好的方法是什么? 有没有我没想过的含义? 还有其他选择吗?

在内存中加载文本文件的最快/最干净的方法

我之前已经问过类似的问题,但我找不到能回答我确切问题的问题。 我需要一种方法来将文件读取为具有最少代码的String ,并尽可能简单和最佳。 我不是在寻找: final BufferedReader br = new BufferedReader(new FileReader(file)); String line = null; while ((line = br.readLine()) != null) { // logic } 而且我知道我可以写自己的助手类来做到这一点。 我正在寻找更多的东西: final String wholeFileAsStr = Something.load(file); 其中Something.load()是超级优化的,并在读取文件时正确缓冲文件,例如考虑文件大小。 任何人都可以推荐一些我不知道的Guava或Apache的东西吗? 提前致谢。

创建长度为N的新数组的最快方法,并通过重复给定数组来填充它

我想分配一个长度为N的新数组,并通过重复给定的数组来填充它。 界面如下所示: T[] repeat(T[] array, int n); 澄清我的意思是一个小例子: String a = {“a”, “b”, “c”}; // b = {“a”, “b”, “c”, “a”, “b”, “c”, “a”, “b”, “c”, “a”} String b = repeat(a, 10); 大多数程序员都会提出以下解决方案(为了简化数组生成,选择了特定类型): public String[] repeat(String[] array, int n) { String[] repeated = new String[n]; for (int i = 0; i < n; i++) { […]

Java默认方法比相同的代码慢,但在抽象类中

我有一个PackedObject接口: public interface PackedObject { int get(); int sum(); void setIndex(int index); default int defaultSum() { return get(); } } 抽象类AbstractPackedObject : public abstract class AbstractPackedObject implements PackedObject { protected int index = 0; protected int[] buffer; public void setIndex(int index) { this.index = index; } public void setBuffer(int[] buffer) { this.buffer = buffer; } […]

性能:从HashMap.values()创建一个ArrayList

问题是从HashMap.values()集合创建ArrayList的成本是多少? 或者单独创建值Collection? 假设Map.size()> 100k。 对象也可以一直保存在ArrayList(而不是HashMap)中,这对其他部分有影响(元素的修改,易于按键)。 ArrayList用于迭代每个第n个元素。 (这就是为什么不能直接使用值集合)。 在迭代期间不进行任何修改。

Javaarrays与C ++arrays中的性能和内存使用情况

我在一家小公司工作,在那里我建立一些银行软件。 现在,我必须构建一些数据结构,如: Array [Int-Max] [2] // Large 2D array 将其保存到磁盘并在第二天加载它以备将来工作。 现在,因为我只知道Java(和一点点C),他们总是坚持使用C ++或C.根据他们的建议: 他们已经看到Java中的Array [Int-Max] [2]占用的内存几乎是C的1.5倍,而C ++占用的内存占用量比Java大一些。 C和C ++可以处理任意大的文件,而Java则无法处理。 根据他们的建议,随着数据库/数据结构变得庞大,Java变得不可行。 由于我们必须处理如此大的数据库/数据结构,因此C / C ++总是更受欢迎。 现在我的问题是, 为什么C或C ++总是优于Java上的大型数据库/数据结构? 因为,C可能是,但C ++也是一个OOP。 那么,它如何获得优于Java的优势? 我应该继续使用Java还是他们的建议(切换到C ++)将来会对大型数据库/数据结构环境有所帮助? 有什么建议吗? 对不起,我对所有这些知识知之甚少,刚开始从事一个项目,所以真的很困惑。 因为到现在为止我刚建了一些学校项目,对相对较大的项目一无所知。

使用最终字段的成本

我们知道最终制作字段通常是一个好主意,因为我们获得了线程安全性和不变性,这使代码更易于推理。 我很好奇是否有相关的性能成本。 Java内存模型保证了final Field Semantics : 在该对象完全初始化之后只能看到对象引用的线程可以保证看到该对象的最终字段的正确初始化值。 这意味着对于像这样的类 class X { X(int a) { this.a = a; } final int a; static X instance; } 每当线程1创建这样的实例时 X.instance = new X(43); while (true) doSomethingEventuallyEvictingCache(); 和线程2看到它 while (X.instance == null) { doSomethingEventuallyEvictingCache(); } System.out.println(X.instance.a); 它必须打印43.如果没有final修饰符,JIT或CPU可以重新排序存储(第一个存储X.instance然后设置a=43 ),线程2可以看到默认初始化值并打印0。 当JIT看到final它显然不会重新排序。 但它也必须强制CPU遵守命令。 是否存在相关的性能损失?

为什么这个代码在锁定时运行得更快?

一些背景:我创建了一个人为的例子来向我的团队展示VisualVM的使用。 特别是,一个方法有一个不必要的synchronized关键字,我们看到线程池中的线程阻塞,它们不需要。 但删除该关键字具有下面描述的令人惊讶的效果,下面的代码是最简单的情况我可以减少原始示例以重现问题,并且使用ReentrantLock也会产生相同的效果。 请考虑以下代码( https://gist.github.com/revbingo/4c035aa29d3c7b50ed8b上的完整可运行代码示例 – 您需要将Commons Math 3.4.1添加到类路径中)。 它创建100个任务,并将它们提交给5个线程的线程池。 在任务中,创建两个500×500随机值矩阵,然后相乘。 public class Main { private static ExecutorService exec = Executors.newFixedThreadPool(5); private final static int MATRIX_SIZE = 500; private static UncorrelatedRandomVectorGenerator generator = new UncorrelatedRandomVectorGenerator(MATRIX_SIZE, new StableRandomGenerator(new JDKRandomGenerator(), 0.1d, 1.0d)); private static ReentrantLock lock = new ReentrantLock(); public static void main(String[] args) throws Exception { […]