Skip to content

Commit e8602ee

Browse files
committed
Port optimized6 from Java to Scala (same performance)
1 parent 8b89be8 commit e8602ee

File tree

4 files changed

+368
-0
lines changed

4 files changed

+368
-0
lines changed

src/com/komanov/ver/Version.scala

+50
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,56 @@ object Version {
195195
def parseOptimized6(v: String): Option[Version] =
196196
Option(ParseVersionUtil.parseHardCore3SingleLoop(v))
197197

198+
def parseOptimized6Scala(v: String): Option[Version] = {
199+
val len = v.length
200+
201+
var major = 0
202+
var minor = 0
203+
204+
var current = 0
205+
var dots = 0
206+
var lastDotIndex = -1
207+
208+
for (i <- 0 until len) {
209+
val ch = v.charAt(i)
210+
val digit = ch - 48
211+
if (digit == -2) {
212+
if (lastDotIndex + 1 == i) {
213+
return None
214+
}
215+
if (current < 0 || current > MaxVersionSize) {
216+
return None
217+
}
218+
219+
dots match {
220+
case 0 =>
221+
major = current
222+
dots = 1
223+
224+
case 1 =>
225+
minor = current
226+
dots = 2
227+
228+
case _ =>
229+
return None
230+
}
231+
lastDotIndex = i
232+
current = 0
233+
} else if (digit < 0 || digit > 9) {
234+
return None
235+
} else { // overflow is possible!
236+
current = current * 10 + digit
237+
}
238+
}
239+
240+
if (dots != 2 || lastDotIndex == len - 1)
241+
None
242+
else if (current < 0 || current > MaxVersionSize)
243+
None
244+
else
245+
Some(Version(major, minor, current))
246+
}
247+
198248
private[ver] def isNumber(s: String, from: Int, to: Int): Boolean = {
199249
// length of MaxVersionSize
200250
val len = to - from

src/com/komanov/ver/VersionNoAlloc.scala

+50
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,56 @@ object VersionNoAlloc {
186186
def parseOptimized6(v: String): Long =
187187
ParseVersionNoAllocUtil.parseHardCore3SingleLoop(v)
188188

189+
def parseOptimized6Scala(v: String): Long = {
190+
val len = v.length
191+
192+
var major = 0
193+
var minor = 0
194+
195+
var current = 0
196+
var dots = 0
197+
var lastDotIndex = -1
198+
199+
for (i <- 0 until len) {
200+
val ch = v.charAt(i)
201+
val digit = ch - 48
202+
if (digit == -2) {
203+
if (lastDotIndex + 1 == i) {
204+
return Invalid
205+
}
206+
if (current < 0 || current > MaxVersionSize) {
207+
return Invalid
208+
}
209+
210+
dots match {
211+
case 0 =>
212+
major = current
213+
dots = 1
214+
215+
case 1 =>
216+
minor = current
217+
dots = 2
218+
219+
case _ =>
220+
return Invalid
221+
}
222+
lastDotIndex = i
223+
current = 0
224+
} else if (digit < 0 || digit > 9) {
225+
return Invalid
226+
} else { // overflow is possible!
227+
current = current * 10 + digit
228+
}
229+
}
230+
231+
if (dots != 2 || lastDotIndex == len - 1)
232+
Invalid
233+
else if (current < 0 || current > MaxVersionSize)
234+
Invalid
235+
else
236+
version(major, minor, current)
237+
}
238+
189239
private[ver] def isNumber(s: String, from: Int, to: Int): Boolean = {
190240
// length of MaxVersionSize
191241
val len = to - from

src/com/komanov/ver/jmh/VersionParseBenchmark.scala

+3
Original file line numberDiff line numberDiff line change
@@ -964,4 +964,7 @@ class VersionParseBenchmark {
964964

965965
@Benchmark
966966
def optimized6: Option[Version] = Version.parseOptimized6(encoded)
967+
968+
@Benchmark
969+
def optimized6Scala: Option[Version] = Version.parseOptimized6Scala(encoded)
967970
}

0 commit comments

Comments
 (0)