Sayısal Değerlerin Karakter Uzunluğunu Bulmanın Hızlı Bir Yöntemi
Diyelim ki çalıştığınız yazılım projesinde şöyle bir şey yapmanız gerekiyor; elinizde çok sayıda Integer değer var ve her birinin karakter uzunluklarını bularak belirlenen sayıdan fazla veya az olanlarını tespit etmelisiniz.
Örneğin; TC Kimlik numarası alanı olan bir kayıt formunda, ön yüz tarafında 11 karakter sınırlaması unutulmuş, bir çok kayıt gerçekleşmiş ve şimdi uygun olmayan kayıtları tespit etmeniz gerekiyor...
Aklınızda canlandığı üzere bir Integer (veya Long, Double, Short, Float, Byte) değerin karakter uzunluğuna hızlıca ulaşmamızı sağlayan hazır bir metod yoktur. Çünkü sayısal değerler; String, List, Array gibi bir dizi yapısında değillerdir. (String: Char’lardan oluşan bir listedir)
Bu sebeple sayısal bir değerin karakter uzunluğuna ulaşmak için farklı yöntemler uygulamamız gerekir. Bu yöntemlerin -öyle zannediyorum ki- akla ilk geleni String’e çevirmektir.
Kotlin dili için örnek kodumuz şu şekilde:
val i = 1234567890
val length = i.toString().length // <---
println("Length: $length")
Bu işlemin hesaplanmış süresi;
- println satırı hariç ortalama: 389us (micro saniye)’dir.
- println satırı dahil ortalama: 2.89ms (milisaniye)’dir.
Bu kodlar arkaplanda, “length” isimli yeni bir değişken oluşturulması, bu değişkene bellekte bir adres atanması, sayısal değerimizin metinsel hâle çevrilmesi ve elde edilen sonucun bu yeni değişkenimize atanması işlemlerini gerçekleştirir.
Bu makalede, amacımız olan “sayısal verinin karakter uzunluğunu bulmak” işlemi için .toString() yönteminden çok daha hızlı bir yöntem önerisinde bulunacağım. Bildiğiniz üzere sayısal verilerin işlenmesi; donanım düzeyinde işlem desteği, sabit bellek kullanımı, adres hesaplamasının hızlı olması gibi sebeplerden ötürü çok hızlı yapılmaktadır. Dolayısıyla sayısal bir değer üzerinde yapılacak ve bizi hedefimize götürebilecek bir işlem yukarıda bahsettiğimiz seçenekten çok daha hızlı tamamlanacaktır.
Bu noktada Log10() metodu bu iş için biçilmiş kaftandır. Aşağıdaki kod örneğini ve hesaplanmış işlem sürelerini inceleyelim.
val i = 1234567890
val length = floor(log10(i.toDouble())).toInt() + 1 // <---
println("Length: $length")
Bu örneğimizde verilen Integer değer önce Double’a çevrilmiş. Sonra log10 methodunda karakter sayısı Double olarak bulunmuş, yuvarlama için floor metodu kullanılmış ve elde edilen sonuca 1 (bir) eklenmiştir.
Bu işlemlerin hesaplanmış süresi;
- println satırı hariç ortalama: 8.458us’dir.
- println satırı dahil ortalama: 105.333us’dir.
İki yöntem arasında kıyaslama yapıldığında Log10 yönteminin -println satırı hariç ölçümlerde- 46 kat daha hızlı çalıştığı görülmektedir.
Bir kaç sayısal değerin karakter uzunluğunu bulmaya çalışırken bu süre farkları gözardı edilebilir belki fakat binlerce, milyonlarca veri ile işlem yaparken kullanılmasında fayda olacaktır diye düşünüyorum.
Not: İşlem süreleri işlemci ve bellek tipi, özelliği ve anlık yoğunluğuna göre değişkenlik gösterebilir. Tam kodu Android Studio’da çalıştırıp sonucu kendiniz görebilirsiniz.
import kotlin.math.floor
import kotlin.math.log10
import kotlin.time.Duration
import kotlin.time.measureTime
/**
* Created by Murat Yüksektepe - yuksektepemurat@gmail.com on 30.05.2025.
*/
fun main() {
val integer = 1234567890
val measureTime1 = integer.findIntLengthWithToString()
val measureTime2 = integer.findIntLengthWithLog10()
val measureTimeRatio = measureTime1.inWholeNanoseconds / measureTime2.inWholeNanoseconds
println("measureTime 1: $measureTime1")
println("measureTime 2: $measureTime2")
println("Result: measureTime 1, $measureTimeRatio times bigger than measureTime 2")
}
fun Int.findIntLengthWithToString(): Duration {
return measureTime {
val length = this.toString().length
// println("Length: $length")
}
}
fun Int.findIntLengthWithLog10(): Duration {
return measureTime {
val length = floor(log10(this.toDouble())).toInt() + 1
// println("Length: $length")
}
}