aboutsummaryrefslogtreecommitdiff
path: root/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferUtf8Benchmark.java
blob: 61ea059c4b02c3f5ca5846d91159ea4d16d464fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright (C) 2018 Square, Inc. and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.okio.benchmarks;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.Main;
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.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.RunnerException;

import okio.Buffer;
import okio.ByteString;

@Fork(1)
@Warmup(iterations = 5, time = 2)
@Measurement(iterations = 5, time = 2)
@State(Scope.Benchmark)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public class BufferUtf8Benchmark {
  private static final Map<String, String> strings = new HashMap<>();

  static {
    strings.put(
        "ascii",
        "Um, I'll tell you the problem with the scientific power that you're using here, "
            + "it didn't require any discipline to attain it. You read what others had done and you "
            + "took the next step. You didn't earn the knowledge for yourselves, so you don't take any "
            + "responsibility for it. You stood on the shoulders of geniuses to accomplish something "
            + "as fast as you could, and before you even knew what you had, you patented it, and "
            + "packaged it, and slapped it on a plastic lunchbox, and now you're selling it, you wanna "
            + "sell it.");

    strings.put(
        "utf8",
        "Սm, I'll 𝓽𝖾ll ᶌօ𝘂 ᴛℎ℮ 𝜚𝕣०bl𝖾m wі𝕥𝒽 𝘵𝘩𝐞 𝓼𝙘𝐢𝔢𝓷𝗍𝜄𝚏𝑖c 𝛠𝝾w𝚎𝑟 𝕥h⍺𝞃 𝛄𝓸𝘂'𝒓𝗲 υ𝖘𝓲𝗇ɡ 𝕙𝚎𝑟e, "
            + "𝛊𝓽 ⅆ𝕚𝐝𝝿'𝗍 𝔯𝙚𝙦ᴜ𝜾𝒓𝘦 𝔞𝘯𝐲 ԁ𝜄𝑠𝚌ι𝘱lι𝒏e 𝑡𝜎 𝕒𝚝𝖙𝓪і𝞹 𝔦𝚝. 𝒀ο𝗎 𝔯𝑒⍺𝖉 w𝐡𝝰𝔱 𝞂𝞽һ𝓮𝓇ƽ հ𝖺𝖉 ⅾ𝛐𝝅ⅇ 𝝰πԁ 𝔂ᴑᴜ 𝓉ﮨ၀𝚔 "
            + "т𝒽𝑒 𝗇𝕖ⅹ𝚝 𝔰𝒕е𝓅. 𝘠ⲟ𝖚 𝖉ⅰԁ𝝕'τ 𝙚𝚊r𝞹 𝘵Ꮒ𝖾 𝝒𝐧هwl𝑒𝖉ƍ𝙚 𝓯૦r 𝔂𝞼𝒖𝕣𝑠𝕖l𝙫𝖊𝓼, 𐑈о y𝘰𝒖 ⅆە𝗇't 𝜏α𝒌𝕖 𝛂𝟉ℽ "
            + "𝐫ⅇ𝗌ⲣ๐ϖ𝖘ꙇᖯ𝓲l𝓲𝒕𝘆 𝐟𝞼𝘳 𝚤𝑡. 𝛶𝛔𝔲 s𝕥σσ𝐝 ﮩ𝕟 𝒕𝗁𝔢 𝘴𝐡𝜎ᴜlⅾ𝓮𝔯𝚜 𝛐𝙛 ᶃ𝚎ᴨᎥս𝚜𝘦𝓈 𝓽𝞸 a𝒄𝚌𝞸mρl𝛊ꜱ𝐡 𝓈𝚘m𝚎𝞃𝔥⍳𝞹𝔤 𝐚𝗌 𝖋a𝐬𝒕 "
            + "αs γ𝛐𝕦 𝔠ﻫ𝛖lԁ, 𝚊π𝑑 Ь𝑒𝙛૦𝓇𝘦 𝓎٥𝖚 ⅇvℯ𝝅 𝜅ո𝒆w w𝗵𝒂𝘁 ᶌ੦𝗎 h𝐚𝗱, 𝜸ﮨ𝒖 𝓹𝝰𝔱𝖾𝗇𝓽𝔢ⅆ і𝕥, 𝚊𝜛𝓭 𝓹𝖺ⅽϰ𝘢ℊеᏧ 𝑖𝞃, "
            + "𝐚𝛑ꓒ 𝙨l𝔞р𝘱𝔢𝓭 ɩ𝗍 ہ𝛑 𝕒 pl𝛂ѕᴛ𝗂𝐜 l𝞄ℼ𝔠𝒽𝑏ﮪ⨯, 𝔞ϖ𝒹 n𝛔w 𝛾𝐨𝞄'𝗿𝔢 ꜱ℮ll𝙞nɡ ɩ𝘁, 𝙮𝕠𝛖 w𝑎ℼ𝚗𝛂 𝕤𝓮ll 𝙞𝓉.");

    // The first 't' is actually a '𝓽'
    strings.put(
        "sparse",
        "Um, I'll 𝓽ell you the problem with the scientific power that you're using here, "
            + "it didn't require any discipline to attain it. You read what others had done and you "
            + "took the next step. You didn't earn the knowledge for yourselves, so you don't take any "
            + "responsibility for it. You stood on the shoulders of geniuses to accomplish something "
            + "as fast as you could, and before you even knew what you had, you patented it, and "
            + "packaged it, and slapped it on a plastic lunchbox, and now you're selling it, you wanna "
            + "sell it.");

    strings.put("2bytes", "\u0080\u07ff");

    strings.put("3bytes", "\u0800\ud7ff\ue000\uffff");

    strings.put("4bytes", "\ud835\udeca");

    // high surrogate, 'a', low surrogate, and 'a'
    strings.put("bad", "\ud800\u0061\udc00\u0061");
  }

  @Param({"20", "2000", "200000"})
  int length;

  @Param({"ascii", "utf8", "sparse", "2bytes", "3bytes", "4bytes", "bad"})
  String encoding;

  Buffer buffer;
  String encode;
  ByteString decode;

  @Setup
  public void setup() {
    String part = strings.get(encoding);

    // Make all the strings the same length for comparison
    StringBuilder builder = new StringBuilder(length + 1_000);
    while (builder.length() < length) {
      builder.append(part);
    }
    builder.setLength(length);

    // Prepare a string and ByteString for encoding and decoding
    buffer = new Buffer();
    encode = builder.toString();
    Buffer temp = new Buffer();
    temp.writeUtf8(encode);
    decode = temp.snapshot();
  }

  @Benchmark
  public void writeUtf8() {
    buffer.writeUtf8(encode);
    buffer.clear();
  }

  @Benchmark
  public String readUtf8() {
    buffer.write(decode);
    return buffer.readUtf8();
  }

  public static void main(String[] args) throws IOException, RunnerException {
    Main.main(new String[] {BufferUtf8Benchmark.class.getName()});
  }
}