问题: 我有一个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个元素的地图
做过
没有类型转换的运行测试
nums:-1650117013
整数:-1650117013
2097538520个
用类型转换运行测试
nums:-1650117013
整数:-1650117013
25423803480
- &GT;在第一种情况下大约2秒,在第二种情况下反对25秒!
答案 0 :(得分:3)
正如您所见,Map[A,B]
在密钥类型A
中是非变量的,因此您需要某种转换才能分配给Map[A,B]
类型的变量a { {1}} Map[A1,B]
。但是,如果您可以更改A1 <: A
的定义,则可以尝试以下内容:
def processNumbers(nums: Map[Number, String])
并传递def processNumbers[T <: Number](nums: Map[T, String])
而不进行转换。
这有助于解决您的问题吗?