Optimize JsonObjectParser.isWhitespace by replacing Set.contains with match using table switch (#25260)
This commit is contained in:
parent
427124a531
commit
b8230a38b7
3 changed files with 43 additions and 34 deletions
|
|
@ -15,44 +15,37 @@ import org.openjdk.jmh.annotations._
|
|||
@BenchmarkMode(Array(Mode.Throughput))
|
||||
class JsonFramingBenchmark {
|
||||
|
||||
/*
|
||||
Benchmark Mode Cnt Score Error Units
|
||||
// old
|
||||
JsonFramingBenchmark.collecting_1 thrpt 20 81.476 ± 14.793 ops/s
|
||||
JsonFramingBenchmark.collecting_offer_5 thrpt 20 20.187 ± 2.291 ops/s
|
||||
|
||||
// new
|
||||
JsonFramingBenchmark.counting_1 thrpt 20 10766.738 ± 1278.300 ops/s
|
||||
JsonFramingBenchmark.counting_offer_5 thrpt 20 28798.255 ± 2670.163 ops/s
|
||||
*/
|
||||
|
||||
val json =
|
||||
ByteString(
|
||||
"""{"fname":"Frank","name":"Smith","age":42,"id":1337,"boardMember":false}"""
|
||||
)
|
||||
|
||||
val json5 =
|
||||
ByteString(
|
||||
"""|{"fname":"Frank","name":"Smith","age":42,"id":1337,"boardMember":false},
|
||||
|{"fname":"Bob","name":"Smith","age":42,"id":1337,"boardMember":false},
|
||||
|{"fname":"Bob","name":"Smith","age":42,"id":1337,"boardMember":false},
|
||||
|{"fname":"Bob","name":"Smith","age":42,"id":1337,"boardMember":false},
|
||||
|{"fname":"Bob","name":"Smith","age":42,"id":1337,"boardMember":false},
|
||||
|{"fname":"Bob","name":"Smith","age":42,"id":1337,"boardMember":false},
|
||||
|{"fname":"Hank","name":"Smith","age":42,"id":1337,"boardMember":false}""".stripMargin
|
||||
|{"fname":"Bob","name":"Smith","age":42,"id":1337,"boardMember":false},
|
||||
|{"fname":"Bob","name":"Smith","age":42,"id":1337,"boardMember":false},
|
||||
|{"fname":"Bob","name":"Smith","age":42,"id":1337,"boardMember":false},
|
||||
|{"fname":"Hank","name":"Smith","age":42,"id":1337,"boardMember":false}""".stripMargin
|
||||
)
|
||||
|
||||
val jsonLong =
|
||||
ByteString(
|
||||
s"""{"fname":"Frank","name":"Smith","age":42,"id":1337,"boardMember":false,"description":"${"a" * 1000000}"}"""
|
||||
)
|
||||
|
||||
val bracket = new JsonObjectParser
|
||||
|
||||
@Setup(Level.Invocation)
|
||||
def init(): Unit = {
|
||||
bracket.offer(json)
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
def counting_1: ByteString =
|
||||
def counting_1: ByteString = {
|
||||
bracket.offer(json)
|
||||
bracket.poll().get
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@OperationsPerInvocation(5)
|
||||
def counting_offer_5: ByteString = {
|
||||
bracket.offer(json)
|
||||
bracket.poll().get
|
||||
bracket.offer(json5)
|
||||
bracket.poll().get
|
||||
bracket.poll().get
|
||||
bracket.poll().get
|
||||
|
|
@ -60,4 +53,10 @@ class JsonFramingBenchmark {
|
|||
bracket.poll().get
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
def counting_long_document: ByteString = {
|
||||
bracket.offer(jsonLong)
|
||||
bracket.poll().get
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,4 +2,11 @@
|
|||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.javadsl.Flow.takeWhile$default$2")
|
||||
|
||||
# Wrong return type of FlowMonitorState.finished #24885
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.stream.FlowMonitorState.finished")
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.stream.FlowMonitorState.finished")
|
||||
|
||||
# JsonObjectParser.Whitespace removal #25260
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.stream.impl.JsonObjectParser.Whitespace")
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.stream.impl.JsonObjectParser.Tab")
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.stream.impl.JsonObjectParser.Space")
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.stream.impl.JsonObjectParser.LineBreak2")
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.stream.impl.JsonObjectParser.LineBreak")
|
||||
|
|
@ -23,15 +23,18 @@ import scala.annotation.switch
|
|||
final val Backslash = '\\'.toByte
|
||||
final val Comma = ','.toByte
|
||||
|
||||
final val LineBreak = '\n'.toByte
|
||||
final val LineBreak2 = '\r'.toByte
|
||||
final val Tab = '\t'.toByte
|
||||
final val Space = ' '.toByte
|
||||
final val LineBreak = 10 // '\n'
|
||||
final val LineBreak2 = 13 // '\r'
|
||||
final val Tab = 9 // '\t'
|
||||
final val Space = 32 // ' '
|
||||
|
||||
final val Whitespace = Set(LineBreak, LineBreak2, Tab, Space)
|
||||
|
||||
def isWhitespace(input: Byte): Boolean =
|
||||
Whitespace.contains(input)
|
||||
def isWhitespace(b: Byte): Boolean = (b: @switch) match {
|
||||
case Space ⇒ true
|
||||
case LineBreak ⇒ true
|
||||
case LineBreak2 ⇒ true
|
||||
case Tab ⇒ true
|
||||
case _ ⇒ false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue