-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add benchmarks for a bit of fun comparing solana4j implementation for…
… common cryptographic implementations compared with standard libraries
- Loading branch information
Showing
5 changed files
with
238 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#### JMH Benchmarks | ||
|
||
This `solana4j` library re-implements a few crucial pieces of functionality that are in standard crpytographic libraries, | ||
mostly to avoid it requiring any direct dependencies. We thought it would be fun to compare the performance of our implementations | ||
to that of these standard libraries. | ||
|
||
To run the JMH benchmarks, it is easiest to run via `IntelliJ` with the `JMH Java Microbenchmark Harness` plugin installed. | ||
|
||
##### Base58 Encoding | ||
|
||
Dependency Replaced: `org.bitcoinj:bitcoinj-core:0.16.3` | ||
Benchmark Written: `Base58EncodingBenchmark` | ||
|
||
```text | ||
Benchmark Mode Cnt Score Error Units | ||
Base58EncodingBenchmark.base58DecodeBitcoinjImplementation thrpt 10 804003.990 ± 8733.718 ops/s | ||
Base58EncodingBenchmark.base58DecodeSolana4jImplementation thrpt 10 805712.402 ± 10421.606 ops/s | ||
Base58EncodingBenchmark.base58EncodeBitcoinjImplementation thrpt 10 188832.893 ± 2511.813 ops/s | ||
Base58EncodingBenchmark.base58EncodeSolana4jImplementation thrpt 10 188675.567 ± 1932.977 ops/s | ||
``` | ||
|
||
##### Finding whether a point lies on the Ed25519 curve | ||
|
||
Dependency Replaced: `net.i2p.crypto:eddsa:0.3.0` | ||
Benchmark Written: `EddsaPointOnCurveBenchmark` | ||
|
||
```text | ||
Benchmark Mode Cnt Score Error Units | ||
EddsaPointOnCurveBenchmark.pointNotOnCurveEddsaImplementation thrpt 10 148322.070 ± 2213.306 ops/s | ||
EddsaPointOnCurveBenchmark.pointNotOnCurveSolana4jImplementation thrpt 10 83202.803 ± 3213.023 ops/s | ||
EddsaPointOnCurveBenchmark.pointOnCurveEddsaImplementation thrpt 10 83929.318 ± 3607.478 ops/s | ||
EddsaPointOnCurveBenchmark.pointOnCurveSolana4jImplementation thrpt 10 84799.239 ± 5135.192 ops/s | ||
``` | ||
|
||
#### Sha256 Hashing | ||
|
||
Dependency Replaced: `org.bitcoinj:bitcoinj-core:0.16.3` | ||
Benchmark Written: `Sha256HashingBenchmark` | ||
|
||
```text | ||
Benchmark Mode Cnt Score Error Units | ||
Sha256HashingBenchmark.sha256HashBitcoinjImplementation thrpt 10 9082306.173 ± 56286.482 ops/s | ||
Sha256HashingBenchmark.sha256HashSolana4jImplementation thrpt 10 9184423.015 ± 18583.452 ops/s | ||
``` | ||
|
||
|
54 changes: 54 additions & 0 deletions
54
src/jmh/java/com/lmax/solana4j/Base58EncodingBenchmark.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.lmax.solana4j; | ||
|
||
import com.lmax.solana4j.util.Base58; | ||
import org.openjdk.jmh.annotations.Benchmark; | ||
import org.openjdk.jmh.annotations.BenchmarkMode; | ||
import org.openjdk.jmh.annotations.Fork; | ||
import org.openjdk.jmh.annotations.Measurement; | ||
import org.openjdk.jmh.annotations.Mode; | ||
import org.openjdk.jmh.annotations.OutputTimeUnit; | ||
import org.openjdk.jmh.annotations.Scope; | ||
import org.openjdk.jmh.annotations.State; | ||
import org.openjdk.jmh.annotations.Threads; | ||
import org.openjdk.jmh.annotations.Warmup; | ||
import org.openjdk.jmh.infra.Blackhole; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
@BenchmarkMode(Mode.Throughput) | ||
@OutputTimeUnit(TimeUnit.SECONDS) | ||
@Warmup(iterations = 5, time = 1) | ||
@Measurement(iterations = 5, time = 1) | ||
@Fork(2) | ||
@Threads(1) | ||
@State(Scope.Thread) | ||
public class Base58EncodingBenchmark | ||
{ | ||
private static final String BASE58_STRING = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; | ||
private static final byte[] BYTES = BASE58_STRING.getBytes(StandardCharsets.UTF_8); | ||
|
||
@Benchmark | ||
public void base58DecodeSolana4jImplementation(final Blackhole bh) | ||
{ | ||
bh.consume(Base58.decode(BASE58_STRING)); | ||
} | ||
|
||
@Benchmark | ||
public void base58EncodeSolana4jImplementation(final Blackhole bh) | ||
{ | ||
bh.consume(Base58.encode(BYTES)); | ||
} | ||
|
||
@Benchmark | ||
public void base58DecodeBitcoinjImplementation(final Blackhole bh) | ||
{ | ||
bh.consume(org.bitcoinj.core.Base58.decode(BASE58_STRING)); | ||
} | ||
|
||
@Benchmark | ||
public void base58EncodeBitcoinjImplementation(final Blackhole bh) | ||
{ | ||
bh.consume(org.bitcoinj.core.Base58.encode(BYTES)); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
src/jmh/java/com/lmax/solana4j/EddsaPointOnCurveBenchmark.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package com.lmax.solana4j; | ||
|
||
import com.lmax.solana4j.util.Ed25519; | ||
import com.lmax.solana4j.util.TestKeyPairGenerator; | ||
import net.i2p.crypto.eddsa.math.GroupElement; | ||
import org.openjdk.jmh.annotations.Benchmark; | ||
import org.openjdk.jmh.annotations.BenchmarkMode; | ||
import org.openjdk.jmh.annotations.Fork; | ||
import org.openjdk.jmh.annotations.Measurement; | ||
import org.openjdk.jmh.annotations.Mode; | ||
import org.openjdk.jmh.annotations.OutputTimeUnit; | ||
import org.openjdk.jmh.annotations.Scope; | ||
import org.openjdk.jmh.annotations.State; | ||
import org.openjdk.jmh.annotations.Threads; | ||
import org.openjdk.jmh.annotations.Warmup; | ||
import org.openjdk.jmh.infra.Blackhole; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
import static net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable.ED_25519_CURVE_SPEC; | ||
|
||
@BenchmarkMode(Mode.Throughput) | ||
@OutputTimeUnit(TimeUnit.SECONDS) | ||
@Warmup(iterations = 5, time = 1) | ||
@Measurement(iterations = 5, time = 1) | ||
@Fork(2) | ||
@Threads(1) | ||
@State(Scope.Thread) | ||
public class EddsaPointOnCurveBenchmark | ||
{ | ||
private static final byte[] POINT_NOT_ON_CURVE = new byte[] | ||
{ | ||
1, 5, 9, 3, 6, 9, 3, 6, 9, 3, | ||
2, 6, 1, 4, 7, 1, 4, 7, 1, 4, | ||
3, 7, 2, 5, 8, 2, 5, 8, 2, 5, | ||
4, 8 | ||
}; | ||
|
||
private static final byte[] POINT_ON_CURVE = TestKeyPairGenerator.generateSolanaKeyPair().getPublicKeyBytes(); | ||
|
||
@Benchmark | ||
public void pointOnCurveSolana4jImplementation(final Blackhole bh) | ||
{ | ||
bh.consume(Ed25519.isOnCurve(POINT_ON_CURVE)); | ||
} | ||
|
||
@Benchmark | ||
public void pointNotOnCurveSolana4jImplementation(final Blackhole bh) | ||
{ | ||
bh.consume(Ed25519.isOnCurve(POINT_NOT_ON_CURVE)); | ||
} | ||
|
||
@Benchmark | ||
public void pointOnCurveEddsaImplementation(final Blackhole bh) | ||
{ | ||
try | ||
{ | ||
final GroupElement point = ED_25519_CURVE_SPEC.getCurve().createPoint(POINT_ON_CURVE, false); | ||
bh.consume(point.isOnCurve()); | ||
} | ||
catch (final Exception e) | ||
{ | ||
bh.consume(true); | ||
} | ||
} | ||
|
||
@Benchmark | ||
public void pointNotOnCurveEddsaImplementation(final Blackhole bh) | ||
{ | ||
try | ||
{ | ||
final GroupElement point = ED_25519_CURVE_SPEC.getCurve().createPoint(POINT_NOT_ON_CURVE, false); | ||
bh.consume(point.isOnCurve()); | ||
} | ||
catch (final Exception e) | ||
{ | ||
bh.consume(false); | ||
} | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/jmh/java/com/lmax/solana4j/Sha256HashingBenchmark.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.lmax.solana4j; | ||
|
||
import com.lmax.solana4j.util.Sha256; | ||
import org.openjdk.jmh.annotations.Benchmark; | ||
import org.openjdk.jmh.annotations.BenchmarkMode; | ||
import org.openjdk.jmh.annotations.Fork; | ||
import org.openjdk.jmh.annotations.Measurement; | ||
import org.openjdk.jmh.annotations.Mode; | ||
import org.openjdk.jmh.annotations.OutputTimeUnit; | ||
import org.openjdk.jmh.annotations.Scope; | ||
import org.openjdk.jmh.annotations.State; | ||
import org.openjdk.jmh.annotations.Threads; | ||
import org.openjdk.jmh.annotations.Warmup; | ||
import org.openjdk.jmh.infra.Blackhole; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
@BenchmarkMode(Mode.Throughput) | ||
@OutputTimeUnit(TimeUnit.SECONDS) | ||
@Warmup(iterations = 5, time = 1) | ||
@Measurement(iterations = 5, time = 1) | ||
@Fork(2) | ||
@Threads(1) | ||
@State(Scope.Thread) | ||
public class Sha256HashingBenchmark | ||
{ | ||
private static final String RANDOM_STRING = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; | ||
private static final byte[] BYTES = RANDOM_STRING.getBytes(StandardCharsets.UTF_8); | ||
|
||
@Benchmark | ||
public void sha256HashSolana4jImplementation(final Blackhole bh) | ||
{ | ||
bh.consume(Sha256.hash(BYTES)); | ||
} | ||
|
||
@Benchmark | ||
public void sha256HashBitcoinjImplementation(final Blackhole bh) | ||
{ | ||
bh.consume(org.bitcoinj.core.Sha256Hash.hash(BYTES)); | ||
} | ||
|
||
} |