Speed up Acl.fromReader

It should run 9x faster than before now.

Past mistakes:

* InetAddress.parseNumericAddress throws TWO exceptions underthehood if the string passed is invalid. This caused a huge overhead;
* CharSequence.split in Kotlin is EXTREMELY SLOW.
This commit is contained in:
Mygod
2017-12-17 04:43:19 -08:00
parent bc22b0c481
commit 1010edc561
10 changed files with 111 additions and 78 deletions
@@ -25,15 +25,15 @@ import java.util.*
class Subnet(val address: InetAddress, val prefixSize: Int) : Comparable<Subnet> {
companion object {
@Throws(IllegalArgumentException::class)
fun fromString(value: String): Subnet {
val parts = value.split('/')
val addr = parts[0].parseNumericAddress()
return when (parts.size) {
1 -> Subnet(addr, addr.address.size shl 3)
2 -> Subnet(addr, parts[1].toInt())
else -> throw IllegalArgumentException()
}
fun fromString(value: String): Subnet? {
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
val parts = (value as java.lang.String).split("/", 2)
val addr = parts[0].parseNumericAddress() ?: return null
return if (parts.size == 2) try {
Subnet(addr, parts[1].toInt())
} catch (_: NumberFormatException) {
null
} else Subnet(addr, addr.address.size shl 3)
}
}
@@ -11,31 +11,20 @@ import android.support.v4.app.FragmentManager
import android.support.v7.util.SortedList
import android.util.TypedValue
import com.github.shadowsocks.App.Companion.app
import com.github.shadowsocks.JniHelper
import java.lang.reflect.InvocationTargetException
import java.net.Inet4Address
import java.net.InetAddress
import java.net.URLConnection
private val isNumericMethod by lazy { InetAddress::class.java.getMethod("isNumeric", String::class.java) }
private val parseNumericAddressMethod by lazy {
try {
InetAddress::class.java.getMethod("parseNumericAddress", String::class.java)
} catch (_: NoSuchMethodException) {
null
}
}
private val fieldChildFragmentManager by lazy {
val field = Fragment::class.java.getDeclaredField("mChildFragmentManager")
field.isAccessible = true
field
}
fun String.isNumericAddress(): Boolean = isNumericMethod.invoke(null, this) as Boolean
fun String.parseNumericAddress(): InetAddress =
if (parseNumericAddressMethod == null) InetAddress.getByName(this) else try {
parseNumericAddressMethod!!.invoke(null, this) as InetAddress
} catch (exc: InvocationTargetException) {
throw exc.cause ?: exc
}
fun String.isNumericAddress() = parseNumericAddress() != null
fun String.parseNumericAddress() = JniHelper.parseNumericAddress(this)
fun parsePort(str: String?, default: Int, min: Int = 1025): Int {
val x = str?.toIntOrNull() ?: default