上記と同様のアプローチを使用する Android での Kotlin (いずれにせよ Java を使用するため、結果はほぼ同じです) のベンチマークは、実際にcontains
は に似てindexOf
いますが、それを使用しているにもかかわらず、何らかの理由でより高速であることを示しています。
正規表現に関しては、実際のオブジェクトを作成し、さらに先に進むことができるため、遅くなります。
サンプル結果 (ミリ秒単位の時間):
Contains: 0
IndexOf: 5
Matches: 45
コード:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
AsyncTask.execute {
val itemsCount = 1000
val minStringLength = 1000
val maxStringLength = 1000
val list = ArrayList<String>(itemsCount)
val r = Random()
val stringToSearchFor = prepareFakeString(r, 5, 10, ALPHABET_LOWERCASE + ALPHABET_UPPERCASE + DIGITS)
for (i in 0 until itemsCount)
list.add(prepareFakeString(r, minStringLength, maxStringLength, ALPHABET_LOWERCASE + ALPHABET_UPPERCASE + DIGITS))
val resultsContains = ArrayList<Boolean>(itemsCount)
val resultsIndexOf = ArrayList<Boolean>(itemsCount)
val resultsRegEx = ArrayList<Boolean>(itemsCount)
//Contains
var start: Long = System.currentTimeMillis()
var stop: Long = System.currentTimeMillis()
for (str in list) {
resultsContains.add(str.contains(stringToSearchFor))
}
Log.d("AppLog", "Contains: " + (stop - start))
//IndexOf
start = System.currentTimeMillis()
for (str in list) {
resultsIndexOf.add(str.indexOf(stringToSearchFor) >= 0)
}
stop = System.currentTimeMillis()
Log.d("AppLog", "IndexOf: " + (stop - start))
//Matches
val regex = stringToSearchFor.toRegex()
start = System.currentTimeMillis()
for (str in list) {
resultsRegEx.add(regex.find(str) != null)
}
stop = System.currentTimeMillis()
Log.d("AppLog", "Matches: " + (stop - start))
Log.d("AppLog", "checking results...")
var foundIssue = false
for (i in 0 until itemsCount) {
if (resultsContains[i] != resultsIndexOf[i] || resultsContains[i] != resultsRegEx[i]) {
foundIssue = true
break
}
}
Log.d("AppLog", "done. All results are the same?${!foundIssue}")
}
}
companion object {
const val ALPHABET_LOWERCASE = "qwertyuiopasdfghjklzxcvbnm"
const val ALPHABET_UPPERCASE = "QWERTYUIOPASDFGHJKLZXCVBNM"
const val DIGITS = "1234567890"
fun prepareFakeString(r: Random, minLength: Int, maxLength: Int, charactersToChooseFrom: String): String {
val length = if (maxLength == minLength) maxLength else r.nextInt(maxLength - minLength) + minLength
val sb = StringBuilder(length)
for (i in 0 until length)
sb.append(charactersToChooseFrom[r.nextInt(charactersToChooseFrom.length)])
return sb.toString()
}
}
}