我正在尝试使用 Unsafe 来迭代内存,而不是迭代 byte[] 中的值。使用 unsafe 分配内存块。内存足以容纳 65536 个字节的值。
我正在尝试这个:
char aChar = some character
if ((byte) 0 == (unsafe.getByte(base_address + aChar) & mask)){
// do something
}
代替:
char aChar = some character
if ((byte) 0 == ( lookup[aChar] & mask )){
// do something
}
我认为Unsafe 可以比使用常规数组访问更快地访问内存,并为每个索引执行索引检查......
jvm 会有一个特殊的操作(不安全)以某种方式使常规数组访问和迭代更快,这只是一厢情愿。在我看来,jvm 在正常的 byte[] 迭代中运行良好,并且使用正常的、纯粹的、vanilla java 代码尽可能快地完成它们。
@millimoose 击中了众所周知的“头上钉子”
“不安全可能对很多事情都有用,但这种级别的微优化不是其中之一。——millimoose”
在非常严格的有限情况下,使用 Unsafe 会更快:
- (仅限 64 位 jvm)对于每个测试只执行一次65535 字节 [] 查找更快。在这种情况下,64 位 jvm 上的 UnsafeLookup_8B 速度提高了 24%。如果测试重复进行,每次测试都进行两次,那么现在正常方法比不安全方法快 30%。在冷 jvm 上的纯解释模式下,Unsafe 到目前为止更快 --- 但只是第一次并且仅适用于小数组大小。在 32 位标准 Oracle JVM 7.x 上,正常比使用 unsafe 快三倍。
使用 Unsafe(在我的测试中)比较慢:
- 在 Oracle java 64 位和 32 位虚拟机上速度较慢
- 较慢的操作系统和机器架构(32 位和 64 位)
即使
server
调用了 jvm 选项也更慢Unsafe 比 9% 或更多慢(1_GB 数组和 UnsafeLookup_8B(fastest one) 在下面的 32 位 jvm 代码中(64 位甚至更慢??))
- Unsafe 在 64 位 jvm 上低于 234% 或更多( 1_MB 数组和 UnsafeLookup_1B (最快)在下面的代码中。
这有什么原因吗?**
当我运行下面发布的代码 YellowB 时(检查 1GB 字节 []),正常情况下也是最快的:
C:\Users\wilf>java -Xms1600m -Xprof -jar "S:\wilf\testing\dist\testing.jar"
initialize data...
initialize data done!
use normalLookup()...
Not found '0'
time : 1967737 us.
use unsafeLookup_1B()...
Not found '0'
time : 2923367 us.
use unsafeLookup_8B()...
Not found '0'
time : 2495663 us.
Flat profile of 26.35 secs (2018 total ticks): main
Interpreted + native Method
0.0% 1 + 0 test.StackOverflow.main
0.0% 1 + 0 Total interpreted
Compiled + native Method
67.8% 1369 + 0 test.StackOverflow.main
11.7% 236 + 0 test.StackOverflow.unsafeLookup_8B
11.2% 227 + 0 test.StackOverflow.unsafeLookup_1B
9.1% 184 + 0 test.StackOverflow.normalLookup
99.9% 2016 + 0 Total compiled
Stub + native Method
0.0% 0 + 1 sun.misc.Unsafe.getLong
0.0% 0 + 1 Total stub
Flat profile of 0.00 secs (1 total ticks): DestroyJavaVM
Thread-local ticks:
100.0% 1 Blocked (of total)
Global summary of 26.39 seconds:
100.0% 2023 Received ticks
C:\Users\wilf>java -version
java version "1.7.0_07"
Java(TM) SE Runtime Environment (build 1.7.0_07-b11)
Java HotSpot(TM) Client VM (build 23.3-b01, mixed mode, sharing)
CPU 为:Intel Core 2 Duo E4600 @ 2.4GHZ 4.00GB(3.25GB 可用) 操作系统:Windows 7 (32)
在带有 Windows 7_64、32 位 java 的 4 核 AMD64 上运行测试:
initialize data...
initialize data done!
use normalLookup()...
Not found '0'
time : 1631142 us.
use unsafeLookup_1B()...
Not found '0'
time : 2365214 us.
use unsafeLookup_8B()...
Not found '0'
time : 1783320 us.
在带有 Windows 7_64、64 位 java 的 4 核 AMD64 上运行测试:
use normalLookup()...
Not found '0'
time : 655146 us.
use unsafeLookup_1B()...
Not found '0'
time : 904783 us.
use unsafeLookup_8B()...
Not found '0'
time : 764427 us.
Flat profile of 6.34 secs (13 total ticks): main
Interpreted + native Method
23.1% 3 + 0 java.io.PrintStream.println
23.1% 3 + 0 test.StackOverflow.unsafeLookup_8B
15.4% 2 + 0 test.StackOverflow.main
7.7% 1 + 0 java.io.DataInputStream.<init>
69.2% 9 + 0 Total interpreted
Compiled + native Method
7.7% 0 + 1 test.StackOverflow.unsafeLookup_1B
7.7% 0 + 1 test.StackOverflow.main
7.7% 0 + 1 test.StackOverflow.normalLookup
7.7% 0 + 1 test.StackOverflow.unsafeLookup_8B
30.8% 0 + 4 Total compiled
Flat profile of 0.00 secs (1 total ticks): DestroyJavaVM
Thread-local ticks:
100.0% 1 Blocked (of total)
Global summary of 6.35 seconds:
100.0% 14 Received ticks
42.9% 6 Compilation