Tag: 性能

按类型划分的弹簧布线比按名称布线要慢

在我的项目中,我正在尝试迁移所有用法 Foo foo = (Foo) beanFactory.getBean(“name”); 成 Foo foo = beanFactory.getBean(Foo.class); 好处是显而易见的:类型安全性,较少复杂的代码,较少的无用常量等。通常,这些线路位于静态遗留环境中,其中这种布线是唯一的选择。 这一切都很好,直到有一天用户开始抱怨来自Spring internals的缓慢。 所以我启动了一个分析器来找到一个热点 org.springframework.beans.factory.support.AbstractBeanFactory::doGetBean(String, Class, Object[], boolean) 这是一个昂贵的电话 Class.isAssignableFrom(anotherClass) 。 我已经快速创建了一个小的性能测试,找出字符串名称和类型查找之间的速度差异是一个百日咳350次(我正在使用StaticApplicationContext进行此测试FAIW)! 在调查这一点时,我发现SPR-6870的票数很高,但由于某种原因没有得到解决。 这导致我尝试解决这个问题 , 这个问题确实显着改善了这种情况,但仍然比使用String查找要快25倍! 事实certificate,这种尝试只解决了一半的问题:它缓存bean的名称以保存在O(n)迭代上,但仍然必须调用isAssignableFrom来validation类型。 所描述的问题不仅与我的场景有关,而且也适用于使用@Autowired bean,并且在循环内创建bean的情况下可能会感觉很难。 其中一个解决方案是覆盖其中一个bean工厂方法并缓存同一类型的is-this-bean类型的检查结果,但显然这应该在Spring中完成而不是在我自己的代码中完成。 是否还有其他人遇到类似问题并找到解决方案?

Arrays.stream(array_name).sum()比迭代方法慢吗?

我编写了一个leetcode问题: https ://ooj.leetcode.com/problems/gas-station/使用Java 8。 当我使用Arrays.stream(integer_array).sum()来计算求和时,我的解决方案得到了TLE,同时使用迭代来接受相同的解决方案来计算数组中元素的总和。 这个问题的最佳时间复杂度是O(n),当我使用Java 8中的流API时,我很惊讶得到TLE。我只在O(n)中实现了解决方案。 import java.util.Arrays; public class GasStation { public int canCompleteCircuit(int[] gas, int[] cost) { int start = 0, i = 0, runningCost = 0, totalGas = 0, totalCost = 0; totalGas = Arrays.stream(gas).sum(); totalCost = Arrays.stream(cost).sum(); // for (int item : gas) totalGas += item; // for (int item […]

检查两个整数是否在0的同一侧的最快方法

我需要检查两个整数是否在零的同一侧多次。 我不在乎它是积极的还是消极的,只是它是同一面……而且表现非常重要。 目前我这样做: if (int1 == 0 || int2 == 0) { // handle zero } else if ((int1 ^ int2) > 0) { // different side } else { // same side } 这比速度提高30%(用卡尺测试)更明显: if ((int1 > 0 && int2 > 0) || (int1 < 0 && int2 < 0)) { 可以更快地完成吗? 如果有人想看到我用于30%的测试框架,它就在这里。 我使用了卡尺0.5-rc1 […]

为什么字节码可能比本机代码运行得更快

Java很慢。 这不仅仅是一个“都市传奇”,它似乎是一个事实。 由于延迟,您不会将其用于实时编码,也不会将其用于群集/并行计算。 有数以千计的基准测试,特别是“Java vs C#vs C ++”。 http://benchmarksgame.alioth.debian.org/ 根据上面的网站,不仅Java性能几乎和C一样好(远远不是其他),但Scala和Clojure(两种在JVM上运行的函数语言)都具有比OCaml,Erlang更好的性能。 并且有很多“Java比X更快”,(例如,这里有关于SO的问题: Java运行时性能与本机C / C ++代码? )。 因此,对于某些情况,Java似乎很快。 有人可以解释原因吗? 为什么字节码可能比本机代码运行得更快,在某些情况下,给定动态代码(Scala,Clojure)和垃圾收集? 为什么如果它更快,仍有延迟? 这似乎是一个矛盾,有人可以摆脱光明吗?

为什么Netty表现不佳?

我用这个例子进行性能测试 有人说netty的表现如此之快。 它可以处理1,00,000+并发请求/秒(请查看以下链接) http://www.jboss.org/netty/performance/20090303-mheath.html http://www.jboss.org/netty/performance/20090607-asalihefendic.html 但是当我尝试使用这个例子时,它只给我107个req / sec,并且有1000个并发请求 ab -n 10000 -c 1000 http://localhost:8080/ Server Software: Server Hostname: localhost Server Port: 8080 Document Path: / Document Length: 230 bytes Concurrency Level: 1000 Time taken for tests: 92.784 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 2900000 bytes HTML transferred: 2300000 bytes […]

如果执行顺序(几乎)不受影响,如何在严重的性能下降中分配变量结果?

在玩multithreading时,我可以观察到与AtomicLong(以及使用它的类,例如java.util.Random)相关的一些意外但严重的性能问题,我目前没有解释。 但是,我创建了一个简约示例,它基本上由两个类组成:一个类“Container”,它保存对volatile变量的引用;一个类“DemoThread”,它在线程执行期间对“Container”的实例进行操作。 请注意,对“Container”和volatile long的引用是私有的,并且从不在线程之间共享(我知道这里不需要使用volatile,它仅用于演示目的) – 因此,“DemoThread”的多个实例应该完美运行在多处理器机器上并行,但由于某种原因,它们没有(完整的例子在这篇文章的底部)。 private static class Container { private volatile long value; public long getValue() { return value; } public final void set(long newValue) { value = newValue; } } private static class DemoThread extends Thread { private Container variable; public void prepare() { this.variable = new Container(); } public void run() […]

Java Mutable BigInteger类

我正在使用BigIntegers进行计算,它使用一个调用multiply()大约1000亿次的循环,而BigInteger创建的新对象使得它非常慢。 我希望有人写过或找到了MutableBigInteger类。 我在java.math包中找到了MutableBigInteger,但它是私有的,当我将代码复制到一个新类时,会出现很多错误,其中大部分都是我不知道如何修复的。 像MutableBigInteger这样的Java类有哪些实现允许修改值?

Apache POI性能

我遇到Apache POI的性能问题。 我已经阅读了FAQ,它指的是性能测试。 我已经通过注销和4gb堆运行此测试,我无法让测试运行得超过22秒。 这是我正在运行的测试: http : //svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/SSPerformanceTest.java 常见问题解答说,如果我不能让这个测试在3秒内运行,有50,000行和50列“问题在于您的环境”。 我已经阅读了围绕网络的其他评论,指的是禁用poi日志记录并增加堆大小,但似乎没有任何帮助。 我还可以检查什么来修复我的环境? 机器规格(个人台式机): CPU:Intel i7 8核 内存:16GB 操作系统:Windows 7 64位 JDK:1.8.0_66 POI:3.13 JVM参数:-Xmx4g -Xms4g -Dorg.apache.poi.util.POILogger = org.apache.poi.util.NullLogger 命令参数:XSSF 50000 50 0 我还要提一下,我使用的Apache POIjar子来自maven central 我在github上创建了一个测试项目,您可以在其中简单地克隆项目并运行: mvn exec:java 我对我正在使用的参数进行了硬编码,因此您无需在命令行中输入任何特殊内容。 文档说这应该在3秒内运行。 测试项目位于: https : //github.com/mikedehaan/poi-test

为什么Arrays.equals(char ,char )比其他所有版本快8倍?

短篇故事 基于我对几个不同的Oracle和OpenJDK实现的测试,似乎Arrays.equals(char[], char[])比其他类型的所有其他变体快8倍 。 如果你的应用程序的性能与比较数组的相等性非常相关,那么这意味着你非常希望将所有数据强制转换为char[] ,只是为了获得这种神奇的性能提升。 很长的故事 最近我写了一些高性能代码,它使用Arrays.equals(…)来比较用于索引到结构的键。 密钥可能很长,并且通常只在后面的字节中有所不同,因此这种方法的性能非常重要。 有一次我使用了char[]类型的键,但作为泛化服务的一部分并避免来自byte[]和ByteBuffer底层源的一些副本,我将其更改为byte[] 。 突然2 ,许多基本操作的表现下降了约3倍。 我追溯了上述事实: Arrays.equals(char[], char[])似乎在所有其他Arrays.equals()版本中享有特殊状态,包括一个Arrays.equals() short[] ,它在语义上是相同的(并且可以使用相同的底层代码实现,因为签名不会影响equals的行为)。 所以我写了一个JMH基准测试来测试Arrays.equals(…) 1的所有原始变体,而char[]变体压缩所有其他变体,如上所示。 现在,~8x变种的这种优势并没有扩大到更小或更大的arrays – 但它仍然更快。 对于小型arrays,似乎常数因素开始占主导地位,对于较大的arrays,L2 / L3或主内存带宽开始发挥作用(您可以在前面的图中很清楚地看到后者的效果,其中int[]尤其是long[]数组在大尺寸时的性能开始下降。 这是一个相同的测试,但是有一个较小的小数组和较大的大数组: 在这里, char[]仍在踢屁股,就像以前一样。 小数组(仅16个元素)的每个元素时间大约是标准时间的两倍,可能是由于函数开销:在大约0.5 ns /元素时, char[]变体对于整个调用仍然只需要大约7.2纳秒,或者我的机器上大约有19个循环 – 因此少量的方法开销会大量削减运行时间(同样,基准开销本身也是几个循环)。 在大端,缓存和/或内存带宽是一个驱动因素 – long[]变体几乎是int[]变体的2倍。 short[] ,尤其是byte[]变体不是很有效(它们的工作集仍然适合我机器中的L3)。 char[]和所有其他内容之间的区别非常大,对于依赖于数组比较的应用程序(这对某些特定域实际上并不常见),尝试将所有数据放入char[]是值得的利用。 呵呵。 是什么赋予了? char是否得到特殊处理,因为它是一些String方法的基础? 它只是JVM优化方法的另一个例子,它在基准测试中受到很大影响,而不是将相同(明显)的优化扩展到其他原始类型(特别是这里相同的 short )? 0 …并且这甚至都不是那么疯狂 – 考虑各种系统,例如,依赖于(冗长的)散列比较以检查值是否相等,或者哈希映射,其中键是长的或可变大小的。 1我没有在结果中包含boolean[] , float[]和double[]或double以避免使图形混乱,但是对于记录boolean[]和float[]执行与int[]相同,而double[]执行与long[]相同的操作。 根据类型的基础大小,这是有道理的。 […]

如何编写代码以提示JVM使用向量操作?

一些相关的问题和一年之久: JVM的JIT编译器是否生成使用向量化浮点指令的代码? 前言:我试图在纯java中执行此操作(没有JNI到C ++,没有GPGPU工作等等)。 我已经进行了分析,并且大部分处理时间来自此方法中的数学运算(可能是95%的浮点数学运算和5%的整数运算)。 我已经将所有Math.xxx()调用减少到足够好的近似值,因此大部分数学运算现在都是浮点数乘以一些加法。 我有一些处理音频处理的代码。 我一直在进行调整,并且已经获得了巨大的收益。 现在我正在研究手动循环展开以查看是否有任何好处(至少手动展开2,我看到大约25%的改进)。 在尝试手动展开4时(由于我展开嵌套循环的两个循环,这开始变得非常复杂)我想知道是否有任何我可以做的提示到jvm在运行时它可以使用向量操作(例如SSE2,AVX等……)。 音频的每个样本都可以完全独立于其他样本计算,这就是为什么我已经能够看到25%的改进(减少浮点计算的依赖性)。 例如,我有4个浮点数,一个用于循环的4个展开中的每一个,以保存部分计算的值。 我如何声明和使用这些浮子很重要吗? 如果我把它变成一个浮点数[4],它会向jvm暗示它们彼此无关,而不是浮动,浮动,浮动,浮动甚至是一类4个公共浮标? 有什么我可以做的没有意义,这会杀死我的代码被矢量化的机会? 我在网上看到有关“正常”编写代码的文章,因为编译器/ jvm知道常见模式以及如何优化它们并且偏离模式可能意味着更少的优化。 但至少在这种情况下,我不会期望将循环展开2以提高性能,因为我知道是否还有其他任何我可以做(或者至少不做)来帮助我机会。 我知道编译器/ jvm只会变得更好所以我也要警惕做将来会伤害我的事情。 为好奇者编辑:在2次展开时,将4次性能提升另外约25%,因此我认为如果jvm支持它(或者可能已经使用它们),向量操作将对我的情况有所帮助。 谢谢!