expo-benchmark 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,6 +43,6 @@ android {
43
43
  }
44
44
 
45
45
  dependencies {
46
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
47
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
46
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
47
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
48
48
  }
@@ -2,12 +2,15 @@ package expo.modules.benchmark
2
2
 
3
3
  import expo.modules.kotlin.modules.Module
4
4
  import expo.modules.kotlin.modules.ModuleDefinition
5
- import kotlinx.coroutines.*
5
+ import expo.modules.kotlin.Promise
6
6
  import java.security.MessageDigest
7
+ import java.util.concurrent.Executors
7
8
  import java.util.concurrent.atomic.AtomicLong
8
9
  import kotlin.random.Random
9
10
 
10
11
  class ExpoBenchmarkModule : Module() {
12
+ private val executor = Executors.newCachedThreadPool()
13
+
11
14
  override fun definition() = ModuleDefinition {
12
15
  Name("ExpoBenchmark")
13
16
 
@@ -20,28 +23,50 @@ class ExpoBenchmarkModule : Module() {
20
23
  }
21
24
 
22
25
  // Run a configurable benchmark
23
- AsyncFunction("runBenchmarkAsync") { options: Map<String, Any>? ->
26
+ AsyncFunction("runBenchmarkAsync") { options: Map<String, Any>?, promise: Promise ->
24
27
  val durationSeconds = (options?.get("durationSeconds") as? Number)?.toDouble() ?: 5.0
25
28
  val threads = (options?.get("threads") as? Number)?.toInt() ?: 1
26
29
  val actualThreads = if (threads == 0) Runtime.getRuntime().availableProcessors() else threads
27
30
 
28
- runBenchmark(durationSeconds, actualThreads)
31
+ executor.execute {
32
+ try {
33
+ val result = runBenchmark(durationSeconds, actualThreads)
34
+ promise.resolve(result)
35
+ } catch (e: Exception) {
36
+ promise.reject("BENCHMARK_ERROR", e.message, e)
37
+ }
38
+ }
29
39
  }
30
40
 
31
41
  // Quick single-threaded benchmark
32
- AsyncFunction("runQuickBenchmarkAsync") {
33
- runBenchmark(1.0, 1)
42
+ AsyncFunction("runQuickBenchmarkAsync") { promise: Promise ->
43
+ executor.execute {
44
+ try {
45
+ val result = runBenchmark(1.0, 1)
46
+ promise.resolve(result)
47
+ } catch (e: Exception) {
48
+ promise.reject("BENCHMARK_ERROR", e.message, e)
49
+ }
50
+ }
34
51
  }
35
52
 
36
53
  // Multi-threaded benchmark using all cores
37
- AsyncFunction("runMultiThreadedBenchmarkAsync") { durationSeconds: Double? ->
54
+ AsyncFunction("runMultiThreadedBenchmarkAsync") { durationSeconds: Double?, promise: Promise ->
38
55
  val duration = durationSeconds ?: 5.0
39
56
  val threads = Runtime.getRuntime().availableProcessors()
40
- runBenchmark(duration, threads)
57
+
58
+ executor.execute {
59
+ try {
60
+ val result = runBenchmark(duration, threads)
61
+ promise.resolve(result)
62
+ } catch (e: Exception) {
63
+ promise.reject("BENCHMARK_ERROR", e.message, e)
64
+ }
65
+ }
41
66
  }
42
67
  }
43
68
 
44
- private suspend fun runBenchmark(durationSeconds: Double, threads: Int): Map<String, Any> {
69
+ private fun runBenchmark(durationSeconds: Double, threads: Int): Map<String, Any> {
45
70
  val durationMs = (durationSeconds * 1000).toLong()
46
71
  val startTime = System.currentTimeMillis()
47
72
  val endTime = startTime + durationMs
@@ -50,58 +75,56 @@ class ExpoBenchmarkModule : Module() {
50
75
 
51
76
  if (threads == 1) {
52
77
  // Single-threaded benchmark
53
- totalHashes = withContext(Dispatchers.Default) {
54
- var hashCount = 0L
55
- var data = ByteArray(32)
56
- Random.nextBytes(data)
57
-
58
- val digest = MessageDigest.getInstance("SHA-256")
59
-
60
- while (System.currentTimeMillis() < endTime) {
61
- data = digest.digest(data)
62
- hashCount++
63
-
64
- // Report progress every 100000 hashes
65
- if (hashCount % 100000 == 0L) {
66
- val elapsed = System.currentTimeMillis() - startTime
67
- val currentHashrate = hashCount.toDouble() / (elapsed.toDouble() / 1000)
68
-
69
- sendEvent("onProgress", mapOf(
70
- "currentHashCount" to hashCount,
71
- "elapsedMs" to elapsed,
72
- "currentHashrate" to currentHashrate
73
- ))
74
- }
78
+ var hashCount = 0L
79
+ var data = ByteArray(32)
80
+ Random.nextBytes(data)
81
+
82
+ val digest = MessageDigest.getInstance("SHA-256")
83
+
84
+ while (System.currentTimeMillis() < endTime) {
85
+ data = digest.digest(data)
86
+ hashCount++
87
+
88
+ // Report progress every 100000 hashes
89
+ if (hashCount % 100000 == 0L) {
90
+ val elapsed = System.currentTimeMillis() - startTime
91
+ val currentHashrate = hashCount.toDouble() / (elapsed.toDouble() / 1000)
92
+
93
+ sendEvent("onProgress", mapOf(
94
+ "currentHashCount" to hashCount,
95
+ "elapsedMs" to elapsed,
96
+ "currentHashrate" to currentHashrate
97
+ ))
75
98
  }
76
-
77
- hashCount
78
99
  }
100
+
101
+ totalHashes = hashCount
79
102
  } else {
80
103
  // Multi-threaded benchmark
81
- totalHashes = withContext(Dispatchers.Default) {
82
- val hashCounts = Array(threads) { AtomicLong(0) }
83
-
84
- val jobs = (0 until threads).map { threadIndex ->
85
- async {
86
- var hashCount = 0L
87
- var data = ByteArray(32)
88
- Random.nextBytes(data)
89
-
90
- val digest = MessageDigest.getInstance("SHA-256")
91
-
92
- while (System.currentTimeMillis() < endTime) {
93
- data = digest.digest(data)
94
- hashCount++
95
- }
96
-
97
- hashCounts[threadIndex].set(hashCount)
104
+ val hashCounts = Array(threads) { AtomicLong(0) }
105
+ val threadPool = Executors.newFixedThreadPool(threads)
106
+ val futures = (0 until threads).map { threadIndex ->
107
+ threadPool.submit {
108
+ var hashCount = 0L
109
+ var data = ByteArray(32)
110
+ Random.nextBytes(data)
111
+
112
+ val digest = MessageDigest.getInstance("SHA-256")
113
+
114
+ while (System.currentTimeMillis() < endTime) {
115
+ data = digest.digest(data)
116
+ hashCount++
98
117
  }
118
+
119
+ hashCounts[threadIndex].set(hashCount)
99
120
  }
121
+ }
100
122
 
101
- jobs.awaitAll()
123
+ // Wait for all threads to complete
124
+ futures.forEach { it.get() }
125
+ threadPool.shutdown()
102
126
 
103
- hashCounts.sumOf { it.get() }
104
- }
127
+ totalHashes = hashCounts.sumOf { it.get() }
105
128
  }
106
129
 
107
130
  val actualEndTime = System.currentTimeMillis()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-benchmark",
3
- "version": "0.1.0",
4
- "description": "My new module",
3
+ "version": "0.2.0",
4
+ "description": "Benchmark module to measure SHA-256 hashrate performance on mobile devices",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
7
7
  "scripts": {