加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala专门化用于原始类型的数值运算

发布时间:2020-12-16 18:01:34 所属栏目:安全 来源:网络整理
导读:我写了一个简单的数学函数: def clamp(num: Double,min: Double,max: Double) = if (num min) min else if (num max) max else num 这很简单,直到我需要与Long类型相同的功能.我用类型参数和专业化来概括它: import Ordering.Implicits._def clamp[@specia
我写了一个简单的数学函数:

def clamp(num: Double,min: Double,max: Double) =
  if (num < min) min else if (num > max) max else num

这很简单,直到我需要与Long类型相同的功能.我用类型参数和专业化来概括它:

import Ordering.Implicits._
def clamp[@specialized N: Ordering](num: N,min: N,max: N) =
  if (num < min) min else if (num > max) max else num

它工作,但我发现字节码在引擎盖下进行了大量的装箱和拆箱:

public boolean clamp$mZc$sp(boolean num,boolean min,boolean max,Ordering<Object> evidence$1)
{
  return Ordering.Implicits..MODULE$.infixOrderingOps(BoxesRunTime.boxToBoolean(num),evidence$1).$greater(BoxesRunTime.boxToBoolean(max)) ? max : Ordering.Implicits..MODULE$.infixOrderingOps(BoxesRunTime.boxToBoolean(num),evidence$1).$less(BoxesRunTime.boxToBoolean(min)) ? min : num;
}

public byte clamp$mBc$sp(byte num,byte min,byte max,Ordering<Object> evidence$1)
{
  return Ordering.Implicits..MODULE$.infixOrderingOps(BoxesRunTime.boxToByte(num),evidence$1).$greater(BoxesRunTime.boxToByte(max)) ? max : Ordering.Implicits..MODULE$.infixOrderingOps(BoxesRunTime.boxToByte(num),evidence$1).$less(BoxesRunTime.boxToByte(min)) ? min : num;
}

public char clamp$mCc$sp(char num,char min,char max,Ordering<Object> evidence$1)
{
  return Ordering.Implicits..MODULE$.infixOrderingOps(BoxesRunTime.boxToCharacter(num),evidence$1).$greater(BoxesRunTime.boxToCharacter(max)) ? max : Ordering.Implicits..MODULE$.infixOrderingOps(BoxesRunTime.boxToCharacter(num),evidence$1).$less(BoxesRunTime.boxToCharacter(min)) ? min : num;
}

有没有更好的方法来进行无拳击的广义算术运算?

解决方法

spire project绝对是寻找高性能数值抽象的最佳选择.它的所有类型类都专门用于常见类型,如long,double,float,int.

这是使用spire类型类的方法:

import spire.algebra._
import spire.implicits._
def clamp[@specialized T:Order](a: T,min: T,max: T) =
  if(a < min) min else if(a > max) max else a

这里是专门的字节码(长版本),使用:scala REPL中的javap提取:

public long clamp$mJc$sp(long,long,spire.algebra.Order<java.lang.Object>);
    descriptor: (JJJLspire/algebra/Order;)J
    flags: ACC_PUBLIC
    Code:
      stack=5,locals=8,args_size=5
         0: aload         7
         2: lload_1
         3: lload_3
         4: invokeinterface #96,5           // InterfaceMethod spire/algebra/Order.lt$mcJ$sp:(JJ)Z
         9: ifeq          16
        12: lload_3
        13: goto          35
        16: aload         7
        18: lload_1
        19: lload         5
        21: invokeinterface #99,5           // InterfaceMethod spire/algebra/Order.gt$mcJ$sp:(JJ)Z
        26: ifeq          34
        29: lload         5
        31: goto          35
        34: lload_1
        35: lreturn

正如你所看到的,它正在调用spire.algebra.Order的gt方法的长专用版本,所以没有涉及到拳击.

您还可以注意到,从运算符(<和>)到类型类方法调用的转换不会出现在代码中.这背后的机制非常精细.请参阅Erik Osheim的这篇blog post,他是尖顶的主要作者之一.

但最重要的是,即使代码是通用的,结果也非常快.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读