You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hbase.apache.org by "Charles Connell (Jira)" <ji...@apache.org> on 2025/10/27 20:44:00 UTC

[jira] [Comment Edited] (HBASE-29688) Use VarHandle instead of Unsafe where possible in 3.x

    [ 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/27/25 8:43 PM:
-------------------------------------------------------------------

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
ByteArrayCompareBenchmark.unsafeComparator                      9  thrpt    5  679373509.181 ± 17561676.662  ops/s
ByteArrayCompareBenchmark.unsafeComparator                     33  thrpt    5  412046005.567 ± 25551650.942  ops/s
ByteArrayCompareBenchmark.unsafeComparator                    257  thrpt    5  169960886.832 ±  9793752.909  ops/s
ByteArrayCompareBenchmark.varHandleComparator                   9  thrpt    5  487103012.003 ±  5842773.421  ops/s
ByteArrayCompareBenchmark.varHandleComparator                  33  thrpt    5  312281408.502 ± 11319895.597  ops/s
ByteArrayCompareBenchmark.varHandleComparator                 257  thrpt    5  133557753.922 ±  4077060.935  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator       9  thrpt    5  474057917.767 ± 29268632.793  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator      33  thrpt    5  312999998.024 ±  5646232.939  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator     257  thrpt    5  132833531.369 ±  6260749.122  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
ByteArrayCompareBenchmark.unsafeComparator                      9  thrpt    5  318417708.508 ± 6072564.489  ops/s
ByteArrayCompareBenchmark.unsafeComparator                     33  thrpt    5  175300534.835 ± 3409995.305  ops/s
ByteArrayCompareBenchmark.unsafeComparator                    257  thrpt    5   82865593.629 ± 1073498.160  ops/s
ByteArrayCompareBenchmark.varHandleComparator                   9  thrpt    5  255940141.048 ± 7105789.861  ops/s
ByteArrayCompareBenchmark.varHandleComparator                  33  thrpt    5  134540416.892 ± 1854513.331  ops/s
ByteArrayCompareBenchmark.varHandleComparator                 257  thrpt    5   54486457.058 ± 4494699.622  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator       9  thrpt    5  255147221.627 ± 6375799.084  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator      33  thrpt    5  132934229.619 ± 3607628.153  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator     257  thrpt    5   54864065.799 ± 1420237.829  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:
{code}
# 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
ByteArrayCompareBenchmark.unsafeComparator                      9  thrpt    5  679373509.181 ± 17561676.662  ops/s
ByteArrayCompareBenchmark.unsafeComparator                     33  thrpt    5  412046005.567 ± 25551650.942  ops/s
ByteArrayCompareBenchmark.unsafeComparator                    257  thrpt    5  169960886.832 ±  9793752.909  ops/s
ByteArrayCompareBenchmark.varHandleComparator                   9  thrpt    5  487103012.003 ±  5842773.421  ops/s
ByteArrayCompareBenchmark.varHandleComparator                  33  thrpt    5  312281408.502 ± 11319895.597  ops/s
ByteArrayCompareBenchmark.varHandleComparator                 257  thrpt    5  133557753.922 ±  4077060.935  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator       9  thrpt    5  474057917.767 ± 29268632.793  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator      33  thrpt    5  312999998.024 ±  5646232.939  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator     257  thrpt    5  132833531.369 ±  6260749.122  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
ByteArrayCompareBenchmark.unsafeComparator                      9  thrpt    5  318417708.508 ± 6072564.489  ops/s
ByteArrayCompareBenchmark.unsafeComparator                     33  thrpt    5  175300534.835 ± 3409995.305  ops/s
ByteArrayCompareBenchmark.unsafeComparator                    257  thrpt    5   82865593.629 ± 1073498.160  ops/s
ByteArrayCompareBenchmark.varHandleComparator                   9  thrpt    5  255940141.048 ± 7105789.861  ops/s
ByteArrayCompareBenchmark.varHandleComparator                  33  thrpt    5  134540416.892 ± 1854513.331  ops/s
ByteArrayCompareBenchmark.varHandleComparator                 257  thrpt    5   54486457.058 ± 4494699.622  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator       9  thrpt    5  255147221.627 ± 6375799.084  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator      33  thrpt    5  132934229.619 ± 3607628.153  ops/s
ByteArrayCompareBenchmark.varHandleLittleEndianComparator     257  thrpt    5   54864065.799 ± 1420237.829  ops/s
{code}

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)