जबकि मैं प्रत्यक्ष java.nio.ByteBuffer के पढ़ने के प्रदर्शन का परीक्षण कर रहा था, मैंने देखा कि पूर्ण पढ़ने सापेक्ष पढ़ने से औसत 2x गुना तेज है। इसके अलावा यदि मैं रिश्तेदार बनाम पूर्ण पढ़ने के स्रोत कोड की तुलना करता हूं, तो कोड रिश्तेदार पढ़ता रहता है और आंतरिक काउंटर को छोड़कर कोड काफी समान होता है। मुझे आश्चर्य है कि मुझे गति में इतना अंतर क्यों दिखता है?डायरेक्ट बाइटबफर रिश्तेदार बनाम पूर्ण पढ़ने का प्रदर्शन
नीचे मेरी JMH बेंचमार्क के स्रोत कोड है:
public class DirectByteBufferReadBenchmark {
private static final int OBJ_SIZE = 8 + 4 + 1;
private static final int NUM_ELEM = 10_000_000;
@State(Scope.Benchmark)
public static class Data {
private ByteBuffer directByteBuffer;
@Setup
public void setup() {
directByteBuffer = ByteBuffer.allocateDirect(OBJ_SIZE * NUM_ELEM);
for (int i = 0; i < NUM_ELEM; i++) {
directByteBuffer.putLong(i);
directByteBuffer.putInt(i);
directByteBuffer.put((byte) (i & 1));
}
}
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public long testReadAbsolute(Data d) throws InterruptedException {
long val = 0l;
for (int i = 0; i < NUM_ELEM; i++) {
int index = OBJ_SIZE * i;
val += d.directByteBuffer.getLong(index);
d.directByteBuffer.getInt(index + 8);
d.directByteBuffer.get(index + 12);
}
return val;
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public long testReadRelative(Data d) throws InterruptedException {
d.directByteBuffer.rewind();
long val = 0l;
for (int i = 0; i < NUM_ELEM; i++) {
val += d.directByteBuffer.getLong();
d.directByteBuffer.getInt();
d.directByteBuffer.get();
}
return val;
}
public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(DirectByteBufferReadBenchmark.class.getSimpleName())
.warmupIterations(5)
.measurementIterations(5)
.forks(3)
.threads(1)
.build();
new Runner(opt).run();
}
}
और ये मेरी बेंचमार्क रन के परिणाम हैं:
Benchmark Mode Cnt Score Error Units
DirectByteBufferReadBenchmark.testReadAbsolute thrpt 15 88.605 ± 9.276 ops/s
DirectByteBufferReadBenchmark.testReadRelative thrpt 15 42.904 ± 3.018 ops/s
परीक्षण एक macbookpro (2.2GHz इंटेल कोर पर चलाया गया था i7, 16 जीबी डीडीआर 3) और जेडीके 1.8.0_73।
अद्यतन
मैं JDK 9-ईए b134 के साथ ही परीक्षण चलाते हैं। दोनों परीक्षण एक ~ 10% गति वृद्धि दिखाते हैं लेकिन दोनों के बीच गति अंतर समान रहता है।
# JMH 1.13 (released 45 days ago)
# VM version: JDK 9-ea, VM 9-ea+134
# VM invoker: /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin/java
# VM options: <none>
Benchmark Mode Cnt Score Error Units
DirectByteBufferReadBenchmark.testReadAbsolute thrpt 15 102.170 ± 10.199 ops/s
DirectByteBufferReadBenchmark.testReadRelative thrpt 15 45.988 ± 3.896 ops/s
आपके उत्तर के लिए धन्यवाद। मैंने जेडीके 9 के साथ परीक्षण किया, सवाल में अपडेट देखें, हालांकि मुझे रिश्तेदार पढ़ने को बेहतर प्रदर्शन करने के लिए नहीं देखा जाता है। कोई विचार क्यों? –
@VladimirG। हां, मेरा बेंचमार्क वास्तव में थोड़ा अलग था। मैंने जवाब अपडेट कर लिया है। कारण अभी भी वही हैं: जेआईटी 'स्थिति' फ़ील्ड के अपडेट को ऑप्टिमाइज़ नहीं करता है, यही कारण है कि रिश्तेदार बाइटबफर का उपयोग कम कुशल प्रतीत होता है। – apangin