0

我有一些代码:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

trait LogicUnit

trait Ezib extends LogicUnit
trait Zieb extends LogicUnit

object LogicUnit {

    @inline 
    def combine[A <: LogicUnit, B <: LogicUnit](arg1: A, arg2: B): Future[LogicUnit] = {

        if (arg1.isInstanceOf[Ezib] && arg2.isInstanceOf[Ezib]) return Future(new Ezib {})
        else if (arg1.isInstanceOf[Zieb] && arg2.isInstanceOf[Zieb]) return Future(new Zieb {})

        else if (arg1.isInstanceOf[Ezib] && arg2.isInstanceOf[Zieb]) return Future(new Zieb {})
        else return Future(new Ezib {})
    }
}

由于这段代码会运行很多,因此我正在尝试对其进行很多优化,因此我正在尝试组合 combine 函数的前两行。为此,我认为代码看起来像这样:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

trait LogicUnit

trait Ezib extends LogicUnit
trait Zieb extends LogicUnit

object LogicUnit {

    @inline 
    def combine[A <: LogicUnit, B <: LogicUnit](arg1: A, arg2: B): Future[LogicUnit] = {

        if (arg1.isInstanceOf[typeOf(arg2)]) return Future(arg1)

        else if (arg1.isInstanceOf[Ezib] && arg2.isInstanceOf[Zieb]) return Future(new Zieb {})
        else return Future(new Ezib {})
    }

}

有什么办法可以让代码检查这两种类型是否相同,这样我就不必匹配所有情况?

4

1 回答 1

2

这里有很多问题:

这些测试不太可能对性能产生任何影响,因为创建和运行 aFuture是一项复杂得多的操作,并且会占主导地位。

类型参数是不必要的,因为值总是被视为LogicUnit这样签名可以是:

def combine(arg1: LogicUnit, arg2: LogicUnit): Future[LogicUnit]

最好使用match而不是isInstanceOf因为编译器知道参数的类型是什么。

第一个版本不依赖于类型,arg1所以不需要测试它:

def combine(arg1: LogicUnit, arg2: LogicUnit): Future[LogicUnit] =
  arg2 match {
    case _: Ezib => Future(new Ezib {})
    case _: Zieb => Future(new Zieb {})
  }

如果您确实需要测试两个参数,请嵌套测试,以免重复第一个测试:

def combine(arg1: LogicUnit, arg2: LogicUnit): Future[LogicUnit] =
  arg1 match {
    case a1: Ezib =>
      arg2 match {
        case a2: Ezib => Future(???)
        case a2: Zieb => Future(???)
      }
    case a1: Zieb =>
      arg2 match {
        case a2: Ezib => Future(???)
        case a2: Zieb => Future(???)
      }
  }

这个公式清晰易读,它允许每个分支使用 和 的值,a1编译a2器知道该值是已匹配的特定类型。

也可能是使用多态版本的combine会提高性能:

def combine(arg1: Ezib, arg2: Ezib): Future[LogicUnit] = ???
def combine(arg1: Ezib, arg2: Zieb): Future[LogicUnit] = ???
def combine(arg1: Zieb, arg2: Ezib): Future[LogicUnit] = ???
def combine(arg1: Zieb, arg2: Zieb): Future[LogicUnit] = ???

def combine(arg1: LogicUnit, arg2: LogicUnit): Future[LogicUnit] =
  arg1 match {
    case a1: Ezib =>
      arg2 match {
        case a2: Ezib => combine(a1, a2)
        case a2: Zieb => combine(a1, a2)
      }
    case a1: Zieb =>
      arg2 match {
        case a2: Ezib => combine(a1, a2)
        case a2: Zieb => combine(a1, a2)
      }
  }

如果在调用点知道具体类型,那么编译器可以直接调用适当的方法,而不必匹配类型。

于 2021-06-09T08:16:19.180 回答