小编Ami*_*adi的帖子

String 构造函数中缺少边界检查消除?

查看 UTF8 解码性能,我注意到 protobuf 的性能UnsafeProcessor::decodeUtf8优于String(byte[] bytes, int offset, int length, Charset charset)以下非 ascii 字符串:"Quizdeltagerne spiste jordb\xc3\xa6r med fl\xc3\x98de, mens cirkusklovnen"

\n

我试图找出原因,所以我复制了相关代码,String并将数组访问替换为不安全的数组访问,与 相同UnsafeProcessor::decodeUtf8。\n以下是 JMH 基准测试结果:

\n
Benchmark                       Mode  Cnt    Score   Error  Units\nStringBenchmark.safeDecoding    avgt   10  127.107 \xc2\xb1 3.642  ns/op\nStringBenchmark.unsafeDecoding  avgt   10  100.915 \xc2\xb1 4.090  ns/op\n
Run Code Online (Sandbox Code Playgroud)\n

我认为差异是由于缺少边界检查消除而导致的,特别是因为checkBoundsOffCount(offset, length, bytes.length)String(byte[] bytes, int offset, int length, Charset charset).

\n

这个问题真的是缺少边界检查消除吗?

\n

这是我使用 OpenJDK 17 和 JMH 进行基准测试的代码。请注意,这只是String(byte[] bytes, …

performance jit jvm-hotspot bounds-check-elimination protobuf-java

11
推荐指数
1
解决办法
445
查看次数

奇怪的泛型问题

有谁知道为什么以下代码不编译和编译期间我得到不兼容的类型异常?

public class Test<T> {

public static void main(String[] args)
{
    // using Test<?> solves the compilation error
    Test test = new Test();

    // getting error incompatible types:
    // found   : java.lang.Object
    // required: java.lang.Integer
    Integer number = test.getDays().get(0);
}


private List<Integer> getDays() {
    return new ArrayList<Integer>();
}
Run Code Online (Sandbox Code Playgroud)

}

为什么使用带有无界通配符的Test解决了这个问题?我正在使用java版本1.6.0_12

java compiler-construction generics

5
推荐指数
2
解决办法
207
查看次数

如何在x86上使用volatile发生丢失更新?

我尝试使用'count'作为volatile运行以下代码:

ExecutorService e = Executors.newFixedThreadPool(2);
for (int i=0; i<2; i++)
{
    e.execute(new Runnable(){
        public void run() {
            for (int i=0; i<1000000; i++)
            count++;
            }
        }
    );
}
e.shutdown();
e.awaitTermination(1, TimeUnit.DAYS);
System.out.println(count);
Run Code Online (Sandbox Code Playgroud)

计数通常最终不到1,000,000.

我正在使用x86处理器 - 英特尔酷睿2双核E8400,热点1.6.24.为了实现原子更新,与volatile运算符一起使用的++运算符通常会丢失更新参数,如下所示:线程1和2都为v读取值0,两者都将其递增1并写入值1.

在x86上使用volatile时,这个论点似乎分崩离析,因为:

1)每次访问volatile变量都会通过CPU缓存层次结构.只有当JVM能够证明单个线程访问volatile变量时,JVM才能生成汇编代码以多次访问volatile,而不会从内存中加载/存储,这不是这里的情况.

2)只有一个CPU可以在修改状态特定的缓存行,所以如果两个CPU试图增加V,只有一个会在获得含钒进入修改状态的高速缓存行成功.另一个将使其高速缓存行无效,并且稍后将进入修改状态,其高速缓存包含正确的值1并将该变量更新为2.

我在这里错过了什么?

java x86 volatile

3
推荐指数
1
解决办法
184
查看次数