Проблема:
У меня есть mutable.Map [Integer, String], я хочу передать его двум методам:
- def processNumbers (nums: Map [Number, String])
- def processIntegers (nums: mutable.Map [Integer, String])
после получения ошибки компиляции я получил следующее:
val ints: mutable.Map[Integer, String] = mutable.Map.empty[Integer, String]
//init of ints
val nums: Map[Number, String] = ints.toMap[Number, String]
processNumbers(nums)
processIntegers(ints)
С небольшим экспериментом я понял, что мой способ сделать это имеет значительные накладные расходы: шаг преобразования типа умножить на 10 на время выполнения.
В общем, преобразование типов действительно просто для того, чтобы порадовать компилятор, так как же это сделать без каких-либо накладных расходов?
Для информации, код моего эксперимента:
package qndTests
import scala.collection.mutable
object TypeTest {
var hashNums = 0
var hashIntegers = 0
def processNumbers(nums: Map[Number, String]): Unit = {
nums.foreach(num =>{
hashNums+=num._1.hashCode+num._2.hashCode
})
}
def processNumbers2(nums: mutable.Map[Integer, String]): Unit = {
nums.foreach(num =>{
hashNums+=num._1.hashCode+num._2.hashCode
})
}
def processIntegers(nums: mutable.Map[Integer, String]): Unit = {
nums.foreach(num =>{
hashIntegers+=num._1.hashCode+num._2.hashCode
})
}
def test(ints: mutable.Map[Integer, String], convertType: Boolean): Unit = {
if(convertType)
println("run test with type conversion")
else
println("run test without type conversion")
val start = System.nanoTime
hashNums = 0
hashIntegers = 0
val nTest = 10
for(i <- 0 to nTest) {
if(convertType){
val nums: Map[Number, String] = ints.toMap[Number, String] //how much does that cost ?
processNumbers(nums)
}else{
processNumbers2(ints)
}
processIntegers(ints)
}
val end= System.nanoTime
println("nums: "+hashNums)
println("ints: "+hashIntegers)
println(end-start)
}
def main(args: Array[String]): Unit = {
val ints: mutable.Map[Integer, String] = mutable.Map.empty[Integer, String]
val testSize = 1000000
println("creating a map of "+testSize+" elements")
for(i <- 0 to testSize) ints.put(i, i.toBinaryString)
println("done")
test(ints, false)
test(ints, true)
}
}
и его вывод:
создание карты из 1000000 элементов
сделано
запустить тест без преобразования типа
номера: -1650117013
целое число: -1650117013
2097538520
запустить тест с преобразованием типов
номера: -1650117013
целое число: -1650117013
25423803480
-> около 2 секунд в первом случае против 25 секунд во втором!