[
https://issues.apache.org/jira/browse/HBASE-29688?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18033324#comment-18033324
]
Charles Connell edited comment on HBASE-29688 at 10/28/25 12:44 AM:
--------------------------------------------------------------------
I've
[benchmarked|https://gist.github.com/charlesconnell/5a9d5a8692b90e37306bacbf744dc106]
the difference between the UnsafeComparer and my proposed replacement:
{noformat}
# Mac M1 Max
# JMH version: 1.37
# VM version: JDK 25, OpenJDK 64-Bit Server VM, 25+36-LTS
# VM options: -Dsun.misc.unsafe.memory.access=allow
XX:+UnlockDiagnosticVMOptions
Benchmark (size) Mode Cnt
Score Error Units
ByteArrayCompareBenchmark.unsafeComparator 9 thrpt 5
680320592.776 ± 10669028.059 ops/s
ByteArrayCompareBenchmark.unsafeComparator 33 thrpt 5
411123019.714 ± 9174574.738 ops/s
ByteArrayCompareBenchmark.unsafeComparator 257 thrpt 5
169957588.048 ± 7244564.892 ops/s
ByteArrayCompareBenchmark.varHandleComparator 9 thrpt 5
483317372.486 ± 8920915.315 ops/s
ByteArrayCompareBenchmark.varHandleComparator 33 thrpt 5
312895075.423 ± 5419468.173 ops/s
ByteArrayCompareBenchmark.varHandleComparator 257 thrpt 5
130359518.026 ± 19797731.032 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 9 thrpt 5
487015103.044 ± 7658548.675 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 33 thrpt 5
310401099.090 ± 10012548.612 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 257 thrpt 5
133024438.066 ± 1640223.556 ops/s# i7ie (Intel Xeon Platinum 8559C) (Emerald
Rapids)
# JMH version: 1.37
# VM version: JDK 25, OpenJDK 64-Bit Server VM, 25+36-LTS
# VM options: -Dsun.misc.unsafe.memory.access=allow
-XX:+UnlockDiagnosticVMOptions
Benchmark (size) Mode Cnt
Score Error Units
ByteArrayCompareBenchmark.unsafeComparator 9 thrpt 5
319163446.681 ± 8445947.323 ops/s
ByteArrayCompareBenchmark.unsafeComparator 33 thrpt 5
177219770.264 ± 2672496.012 ops/s
ByteArrayCompareBenchmark.unsafeComparator 257 thrpt 5
83266642.909 ± 1034901.415 ops/s
ByteArrayCompareBenchmark.varHandleComparator 9 thrpt 5
253008444.287 ± 8409776.956 ops/s
ByteArrayCompareBenchmark.varHandleComparator 33 thrpt 5
131734554.645 ± 675705.993 ops/s
ByteArrayCompareBenchmark.varHandleComparator 257 thrpt 5
54024473.238 ± 4237048.343 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 9 thrpt 5
254502245.915 ± 21794627.432 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 33 thrpt 5
133338993.114 ± 8333740.215 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 257 thrpt 5
54058956.907 ± 543861.480 ops/s# i8g (Graviton 4) (Neoverse V2)
# JMH version: 1.37
# VM version: JDK 25, OpenJDK 64-Bit Server VM, 25+36-LTS
# VM options: -Dsun.misc.unsafe.memory.access=allow
-XX:+UnlockDiagnosticVMOptions
Benchmark (size) Mode Cnt
Score Error Units
ByteArrayCompareBenchmark.unsafeComparator 9 thrpt 5
495298063.874 ± 10659793.142 ops/s
ByteArrayCompareBenchmark.unsafeComparator 33 thrpt 5
331726195.142 ± 13137704.759 ops/s
ByteArrayCompareBenchmark.unsafeComparator 257 thrpt 5
131622968.635 ± 9796113.658 ops/s
ByteArrayCompareBenchmark.varHandleComparator 9 thrpt 5
460653679.323 ± 7878873.128 ops/s
ByteArrayCompareBenchmark.varHandleComparator 33 thrpt 5
277602048.528 ± 3618888.032 ops/s
ByteArrayCompareBenchmark.varHandleComparator 257 thrpt 5
113721719.389 ± 3771209.413 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 9 thrpt 5
451272636.296 ± 11666348.599 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 33 thrpt 5
278145924.392 ± 7196426.885 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 257 thrpt 5
114175291.190 ± 1485438.259 ops/s {noformat}
There is definitely a penalty in switching to VarHandle. However, since Unsafe
is going away eventually, I don't think there is really any choice but to stop
using Unsafe.
was (Author: charlesconnell):
I've
[benchmarked|https://gist.github.com/charlesconnell/5a9d5a8692b90e37306bacbf744dc106]
the difference between the UnsafeComparer and my proposed replacement:
{noformat}
# Mac M1 Max
# JMH version: 1.37
# VM version: JDK 25, OpenJDK 64-Bit Server VM, 25+36-LTS
# VM options: -Dsun.misc.unsafe.memory.access=allow
XX:+UnlockDiagnosticVMOptions
Benchmark (size) Mode Cnt
Score Error Units
ByteArrayCompareBenchmark.unsafeComparator 9 thrpt 5
680320592.776 ± 10669028.059 ops/s
ByteArrayCompareBenchmark.unsafeComparator 33 thrpt 5
411123019.714 ± 9174574.738 ops/s
ByteArrayCompareBenchmark.unsafeComparator 257 thrpt 5
169957588.048 ± 7244564.892 ops/s
ByteArrayCompareBenchmark.varHandleComparator 9 thrpt 5
483317372.486 ± 8920915.315 ops/s
ByteArrayCompareBenchmark.varHandleComparator 33 thrpt 5
312895075.423 ± 5419468.173 ops/s
ByteArrayCompareBenchmark.varHandleComparator 257 thrpt 5
130359518.026 ± 19797731.032 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 9 thrpt 5
487015103.044 ± 7658548.675 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 33 thrpt 5
310401099.090 ± 10012548.612 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 257 thrpt 5
133024438.066 ± 1640223.556 ops/s# i7ie (Intel Xeon Platinum 8559C) (Emerald
Rapids)
# JMH version: 1.37
# VM version: JDK 25, OpenJDK 64-Bit Server VM, 25+36-LTS
# VM options: -Dsun.misc.unsafe.memory.access=allow
-XX:+UnlockDiagnosticVMOptions
Benchmark (size) Mode Cnt
Score Error Units
ByteArrayCompareBenchmark.unsafeComparator 9 thrpt 5
319163446.681 ± 8445947.323 ops/s
ByteArrayCompareBenchmark.unsafeComparator 33 thrpt 5
177219770.264 ± 2672496.012 ops/s
ByteArrayCompareBenchmark.unsafeComparator 257 thrpt 5
83266642.909 ± 1034901.415 ops/s
ByteArrayCompareBenchmark.varHandleComparator 9 thrpt 5
253008444.287 ± 8409776.956 ops/s
ByteArrayCompareBenchmark.varHandleComparator 33 thrpt 5
131734554.645 ± 675705.993 ops/s
ByteArrayCompareBenchmark.varHandleComparator 257 thrpt 5
54024473.238 ± 4237048.343 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 9 thrpt 5
254502245.915 ± 21794627.432 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 33 thrpt 5
133338993.114 ± 8333740.215 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 257 thrpt 5
54058956.907 ± 543861.480 ops/s# i8g (Graviton 4) (Neoverse V2)
# JMH version: 1.37
# VM version: JDK 25, OpenJDK 64-Bit Server VM, 25+36-LTS
# VM options: -Dsun.misc.unsafe.memory.access=allow
-XX:+UnlockDiagnosticVMOptions
Benchmark (size) Mode Cnt
Score Error Units
ByteArrayCompareBenchmark.unsafeComparator 9 thrpt 5
495298063.874 ± 10659793.142 ops/s
ByteArrayCompareBenchmark.unsafeComparator 33 thrpt 5
331726195.142 ± 13137704.759 ops/s
ByteArrayCompareBenchmark.unsafeComparator 257 thrpt 5
131622968.635 ± 9796113.658 ops/s
ByteArrayCompareBenchmark.varHandleComparator 9 thrpt 5
460653679.323 ± 7878873.128 ops/s
ByteArrayCompareBenchmark.varHandleComparator 33 thrpt 5
277602048.528 ± 3618888.032 ops/s
ByteArrayCompareBenchmark.varHandleComparator 257 thrpt 5
113721719.389 ± 3771209.413 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 9 thrpt 5
451272636.296 ± 11666348.599 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 33 thrpt 5
278145924.392 ± 7196426.885 ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator 257 thrpt 5
114175291.190 ± 1485438.259 ops/s {noformat}
There is definitely a penalty in switching to VarHandle. However, since Unsafe
is going away eventually, I don't think there is really any choice but to stop
using Unsafe.
> Use VarHandle instead of Unsafe where possible in 3.x
> -----------------------------------------------------
>
> Key: HBASE-29688
> URL: https://issues.apache.org/jira/browse/HBASE-29688
> Project: HBase
> Issue Type: Improvement
> Reporter: Charles Connell
> Assignee: Charles Connell
> Priority: Minor
> Labels: pull-request-available
>
> Java offers {{VarHandle}} to facilitate fast access to memory, in place of
> the {{Unsafe#get*}} and {{Unsafe#put*}} methods. It can be used as almost a
> drop-in replacement, and the performance is similar. {{VarHandle}} was
> introduced in Java 9. HBase 2.x supports Java 8, so we cannot use
> {{VarHandle}} in 2.x releases, but we can prepare to use it in 3.x releases,
> which target Java 17. This will eliminate most uses of {{Unsafe}} in HBase.
> Remaining uses of {{Unsafe}} are for copying memory regions. There is an
> alternative available for that, {{MemorySegment}}, that is available in Java
> 22 and higher, but we'll tackle that much later.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)