バイト[]の値を反復する代わりに、メモリを反復するためにUnsafeを試しています。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[] 反復で正常に動作し、通常の純粋なバニラ Java コードを使用して、可能な限り高速に実行するようです。
@millimooseは、ことわざの「頭に釘」を打ちます
「安全でないことは多くのことに役立つかもしれませんが、このレベルのマイクロ最適化はその 1 つではありません。 – ミリムース」
Unsafe を使用すると、非常に厳密に制限された一連の状況で高速になります。
- (64 ビット jvm のみ)各テストで1 回だけ実行される単一の 65535 byte[] ルックアップのほうが高速です。この場合、64 ビット jvm の UnsafeLookup_8B は 24% 高速です。各テストが 2 回行われるようにテストが繰り返される場合、通常の方法は安全でない方法より 30% 高速になります。コールド jvm の純粋な解釈モードでは、Unsafe の方がはるかに高速です --- ただし、初回のみで、配列サイズが小さい場合のみです。32 ビット標準の Oracle JVM 7.x では、通常は unsafe を使用するよりも 3 倍高速です。
(私のテストでは) Unsafe を使用すると遅くなります。
- Oracle Java 64 ビットおよび 32 ビット仮想マシンの両方で遅くなる
- OS やマシン アーキテクチャ (32 ビットおよび 64 ビット) に関係なく遅くなる
server
jvm オプションが呼び出されても遅いUnsafe は 9% 以上遅くなります (以下の 32 ビット jvm のコードでは 1_GB 配列と UnsafeLookup_8B(最速のもの) (64 ビットはさらに遅かった??))
- Unsafe は 234% 以上遅い (1_MB 配列と UnsafeLookup_1B (最速のもの) 以下のコードでは、64 ビット jvm で.
これには何らかの理由がありますか?**
以下に投稿されたコード 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 使用可能) OS: 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