@@ -8,6 +8,7 @@ package kotlinx.io.benchmarks
8
8
import kotlinx.benchmark.*
9
9
import kotlinx.io.*
10
10
import kotlinx.io.bytestring.ByteString
11
+ import kotlin.random.Random
11
12
12
13
@State(Scope .Benchmark )
13
14
abstract class BufferRWBenchmarkBase {
@@ -415,3 +416,67 @@ open class IndexOfByteString {
415
416
@Benchmark
416
417
fun benchmark () = buffer.indexOf(byteString)
417
418
}
419
+
420
+ @State(Scope .Benchmark )
421
+ open class Utf8CodePointsBenchmark : BufferRWBenchmarkBase () {
422
+ private val codePointsCount = 128
423
+
424
+ // Encoding names follow naming from Utf8StringBenchmark
425
+ @Param(" ascii" , " utf8" , " sparse" , " 2bytes" , " 3bytes" , " 4bytes" , " bad" )
426
+ var encoding: String = " ascii"
427
+
428
+ override fun padding (): ByteArray {
429
+ return ByteArray (minGap) { ' .' .code.toByte() }
430
+ }
431
+
432
+ private val codePoints = IntArray (codePointsCount)
433
+ private var codePointIdx = 0
434
+
435
+ @Setup
436
+ fun fillCodePointsArray () {
437
+ fun IntArray.fill (generator : () -> Int ) {
438
+ for (idx in this .indices) {
439
+ this [idx] = generator()
440
+ }
441
+ }
442
+
443
+ when (encoding) {
444
+ " ascii" -> codePoints.fill { Random .nextInt(' ' .code, ' ~' .code) }
445
+ " utf8" -> codePoints.fill {
446
+ var cp: Int
447
+ do {
448
+ cp = Random .nextInt(0 , 0x10ffff )
449
+ } while (cp in 0xd800 .. 0xdfff )
450
+ cp
451
+ }
452
+ " sparse" -> {
453
+ codePoints.fill { Random .nextInt(' ' .code, ' ~' .code) }
454
+ codePoints[42 ] = ' ⌛' .code
455
+ }
456
+ " 2bytes" -> codePoints.fill { Random .nextInt(0x80 , 0x800 ) }
457
+ " 3bytes" -> codePoints.fill {
458
+ var cp: Int
459
+ do {
460
+ cp = Random .nextInt(0x800 , 0x10000 )
461
+ } while (cp in 0xd800 .. 0xdfff )
462
+ cp
463
+ }
464
+ " 4bytes" -> codePoints.fill { Random .nextInt(0x10000 , 0x10ffff ) }
465
+ " bad" -> codePoints.fill { Random .nextInt(0xd800 , 0xdfff ) }
466
+ }
467
+ }
468
+
469
+
470
+ private fun nextCodePoint (): Int {
471
+ val idx = codePointIdx
472
+ val cp = codePoints[idx]
473
+ codePointIdx = (idx + 1 ) % codePointsCount
474
+ return cp
475
+ }
476
+
477
+ @Benchmark
478
+ fun benchmark (): Int {
479
+ buffer.writeCodePointValue(nextCodePoint())
480
+ return buffer.readCodePointValue()
481
+ }
482
+ }
0 commit comments