Skip to content

Commit d7ba976

Browse files
committed
JNI-based Iterator benchmark.
Add license notices
1 parent 81d318c commit d7ba976

5 files changed

Lines changed: 342 additions & 0 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Copyright © 2026, Evolved Binary Ltd
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the <organization> nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
#include "Iterator.h"
28+
#include <stdexcept>
29+
#include <algorithm>
30+
31+
Iterator::Iterator(int num_elements, size_t element_size)
32+
: m_num_elements(num_elements), m_element_size(element_size), m_current_index(0) {
33+
34+
m_elements.reserve(num_elements);
35+
36+
std::random_device rd;
37+
std::mt19937 gen(rd());
38+
std::uniform_int_distribution<int> dis(0, 255);
39+
40+
for (int i = 0; i < num_elements; ++i) {
41+
std::vector<char> element(element_size);
42+
std::generate(element.begin(), element.end(), [&]() {
43+
return static_cast<char>(dis(gen));
44+
});
45+
m_elements.push_back(std::move(element));
46+
}
47+
}
48+
49+
bool Iterator::hasNext() const {
50+
return m_current_index < m_num_elements;
51+
}
52+
53+
const std::vector<char>& Iterator::next() {
54+
if (!hasNext()) {
55+
throw std::out_of_range("No more elements in iterator");
56+
}
57+
return m_elements[m_current_index++];
58+
}

src/main/c++/iterators/Iterator.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Copyright © 2026, Evolved Binary Ltd
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the <organization> nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
#ifndef ITERATOR_H
28+
#define ITERATOR_H
29+
30+
#include <vector>
31+
#include <cstddef>
32+
#include <random>
33+
34+
class Iterator {
35+
public:
36+
/**
37+
* @param num_elements Number of elements to generate.
38+
* @param element_size Size of each individual element in bytes.
39+
*/
40+
Iterator(int num_elements, size_t element_size);
41+
42+
/**
43+
* @return true if the iteration has more elements.
44+
*/
45+
bool hasNext() const;
46+
47+
/**
48+
* @return The next element in the iteration.
49+
* Note: In a real Java Iterator, next() returns the element.
50+
* Here we return a pointer to the random data.
51+
*/
52+
const std::vector<char>& next();
53+
54+
private:
55+
int m_num_elements;
56+
size_t m_element_size;
57+
int m_current_index;
58+
std::vector<std::vector<char>> m_elements;
59+
};
60+
61+
#endif // ITERATOR_H
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* Copyright © 2026, Evolved Binary Ltd
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the <organization> nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
#include <jni.h>
28+
#include "Iterator.h"
29+
30+
#ifdef __cplusplus
31+
extern "C" {
32+
#endif
33+
34+
/*
35+
* Class: com_evolvedbinary_jnibench_common_iterators_NativeIterator
36+
* Method: createIterator
37+
* Signature: (IJ)J
38+
*/
39+
JNIEXPORT jlong JNICALL Java_com_evolvedbinary_jnibench_common_iterators_NativeIterator_createIterator
40+
(JNIEnv *env, jobject obj, jint num_elements, jlong element_size) {
41+
Iterator* iterator = new Iterator(num_elements, static_cast<size_t>(element_size));
42+
return reinterpret_cast<jlong>(iterator);
43+
}
44+
45+
/*
46+
* Class: com_evolvedbinary_jnibench_common_iterators_NativeIterator
47+
* Method: hasNext
48+
* Signature: (J)B
49+
*/
50+
JNIEXPORT jboolean JNICALL Java_com_evolvedbinary_jnibench_common_iterators_NativeIterator_hasNext
51+
(JNIEnv *env, jobject obj, jlong handle) {
52+
Iterator* iterator = reinterpret_cast<Iterator*>(handle);
53+
return iterator->hasNext() ? JNI_TRUE : JNI_FALSE;
54+
}
55+
56+
/*
57+
* Class: com_evolvedbinary_jnibench_common_iterators_NativeIterator
58+
* Method: next
59+
* Signature: (J)[B
60+
*/
61+
JNIEXPORT jbyteArray JNICALL Java_com_evolvedbinary_jnibench_common_iterators_NativeIterator_next
62+
(JNIEnv *env, jobject obj, jlong handle) {
63+
Iterator* iterator = reinterpret_cast<Iterator*>(handle);
64+
try {
65+
const std::vector<char>& data = iterator->next();
66+
jbyteArray result = env->NewByteArray(static_cast<jsize>(data.size()));
67+
if (result == nullptr) {
68+
return nullptr;
69+
}
70+
env->SetByteArrayRegion(result, 0, static_cast<jsize>(data.size()), reinterpret_cast<const jbyte*>(data.data()));
71+
return result;
72+
} catch (const std::out_of_range& e) {
73+
jclass exClass = env->FindClass("java/util/NoSuchElementException");
74+
if (exClass != nullptr) {
75+
env->ThrowNew(exClass, e.what());
76+
}
77+
return nullptr;
78+
}
79+
}
80+
81+
/*
82+
* Class: com_evolvedbinary_jnibench_common_iterators_NativeIterator
83+
* Method: disposeInternal
84+
* Signature: (J)V
85+
*/
86+
JNIEXPORT void JNICALL Java_com_evolvedbinary_jnibench_common_iterators_NativeIterator_disposeInternal
87+
(JNIEnv *env, jobject obj, jlong handle) {
88+
Iterator* iterator = reinterpret_cast<Iterator*>(handle);
89+
delete iterator;
90+
}
91+
92+
#ifdef __cplusplus
93+
}
94+
#endif
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright © 2026, Evolved Binary Ltd
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the <organization> nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
package com.evolvedbinary.jnibench.common.iterators;
28+
29+
import com.evolvedbinary.jnibench.common.NativeBackedObject;
30+
31+
public class NativeIterator extends NativeBackedObject {
32+
33+
public NativeIterator(int numElements, long elementSize) {
34+
_nativeHandle = createIterator(numElements, elementSize);
35+
}
36+
37+
public boolean hasNext() {
38+
return hasNext(_nativeHandle);
39+
}
40+
41+
public byte[] next() {
42+
return next(_nativeHandle);
43+
}
44+
45+
@Override
46+
protected void disposeInternal() {
47+
disposeInternal(_nativeHandle);
48+
}
49+
50+
private native long createIterator(int numElements, long elementSize);
51+
private native boolean hasNext(long handle);
52+
private native byte[] next(long handle);
53+
private native void disposeInternal(long handle);
54+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* Copyright © 2026, Evolved Binary Ltd
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the <organization> nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
package com.evolvedbinary.jnibench.jmhbench;
28+
29+
import com.evolvedbinary.jnibench.common.iterators.NativeIterator;
30+
import com.evolvedbinary.jnibench.consbench.NarSystem;
31+
import org.openjdk.jmh.annotations.*;
32+
import org.openjdk.jmh.infra.Blackhole;
33+
34+
import java.util.concurrent.TimeUnit;
35+
36+
/**
37+
* Benchmark for the C++ Iterator via JNI.
38+
*/
39+
@BenchmarkMode(Mode.SampleTime)
40+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
41+
@Warmup(iterations = 10, time = 100, timeUnit = TimeUnit.MILLISECONDS)
42+
@Measurement(iterations = 10, time = 100, timeUnit = TimeUnit.MILLISECONDS)
43+
public class IteratorBenchmark {
44+
45+
static {
46+
NarSystem.loadLibrary();
47+
}
48+
49+
@State(Scope.Benchmark)
50+
public static class BenchmarkState {
51+
52+
@Param({"10", "100", "1000"})
53+
int numElements;
54+
55+
@Param({"16", "128", "1024"})
56+
long elementSize;
57+
58+
@Setup(Level.Iteration)
59+
public void setup() {
60+
}
61+
62+
@TearDown(Level.Iteration)
63+
public void tearDown() {
64+
}
65+
}
66+
67+
@Benchmark
68+
public void iterate(BenchmarkState benchmarkState, Blackhole blackhole) {
69+
try (NativeIterator iterator = new NativeIterator(benchmarkState.numElements, benchmarkState.elementSize)) {
70+
while (iterator.hasNext()) {
71+
blackhole.consume(iterator.next());
72+
}
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)