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

为什么用scala编写的代码比java慢6倍?

发布时间:2020-12-16 09:50:26 所属栏目:安全 来源:网络整理
导读:我不确定我是否在编写 scala代码时犯了一些错误. 问题是: The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832. 73167176531330624919225119674426574742355349194934 96983520312774506326239
我不确定我是否在编写 scala代码时犯了一些错误.
问题是:

The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.

    73167176531330624919225119674426574742355349194934 96983520312774506326239578318016984801869478851843 85861560789112949495459501737958331952853208805511 12540698747158523863050715693290963295227443043557 66896648950445244523161731856403098711121722383113 62229893423380308135336276614282806444486645238749 30358907296290491560440772390713810515859307960866 70172427121883998797908792274921901699720888093776 65727333001053367881220235421809751254540594752243 52584907711670556013604839586446706324415722155397 53697817977846174064955149290862569321978468622482 83972241375657056057490261407972968652414535100474 82166370484403199890008895243450658541227588666881 16427171479924442928230863465674813919123162824586 17866458359124566529476545682848912883142607690042 24219022671055626322222209370544217506941658960408 07198403850962455444362981230987879927244284909188 84580156166097919133875499200524063689912560717606 05886116467109405077541002256983155200055935729725 71636269561882670428252483600823257530420752963450

    Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?

bloger(http://www.ituring.com.cn/article/111574)说他用haskell编写的代码只花了6ms:

import Data.List
    import Data.Char

    main = do
      a <- readFile "008.txt"
      print . maximum . map (product . take 13) . tails $map digitToInt $filter isDigit a

所以我尝试使用scala:

object Main {

      def main(args: Array[String]): Unit = {
        val begin: Long = System.currentTimeMillis()
            val content = Source.fromFile("file/text").filter(_.isDigit).map(_.toInt - '0').toList
            val lists =
              for (i <- 0 to content.size - 13)
                yield content.drop(i).take(13)
            println(lists.maxBy(_.reduce(_ * _)))
        val end: Long = System.currentTimeMillis()
        println(end - begin)
      }
    }

但它平均需要120ms.我认为问题是I / O,但我发现它只花了10ms(我试图使用FileChannel而不是Source,但它不会节省太多时间).它是map和flatmap(for)占用大部分时间的操作.

然后我尝试使用java来查看原因是否是JVM.不足为奇,java版本的运行速度要快得多.大约需要20ms:

public static void main(String[] args) throws IOException {
        long begin = System.currentTimeMillis();

        byte[] bytes = Files.readAllBytes(Paths.get("file/text"));
        List<Integer> list=new ArrayList<>();
        for(int i=0;i<bytes.length;i++){
            if(bytes[i]-'0'>=0&&bytes[i]-'0'<=9) list.add(bytes[i]-'0');
        }

        int max=-1;
        List<Integer> maxList=new ArrayList<>();
        List<Integer> temp=new ArrayList<>();

        for(int i=0;i<=list.size()-13;i++){
            int value=1;
            for(int j=i;j<i+13;j++){
                temp.add(list.get(j));
                value*=list.get(j);
            }
            if(value > max) {
                max = value;
                maxList.clear();
                maxList.addAll(temp);
            }
            temp.clear();
        }
        System.out.println(maxList);
        long end = System.currentTimeMillis();
        System.out.println(end - begin);
    }

我的问题是为什么scala版本的代码运行得如此之慢?

解决方法

正如@etherous所提到的:你在Java版本中使用了可变状态,而你的Scala版本是完全不可变的,而且编写效率也更低.他们只是不同.

您可以尝试避免maxBy,并尝试在一次迭代中保存已计算的结果.这个应该更接近你的Java版本.

val content = Source.fromFile("file/text").filter(_.isDigit).map(_.toLong - '0').toList

val result = (0 to content.size - 13).foldLeft((List.empty[Long],-1l)){case (current @(_,curMax),next) => {
    val temp = content.drop(next).take(13)
    val tempVal = temp.reduce(_*_)
    if(tempVal > curMax) (temp,tempVal) else current
  }
}

结果是这里的一个元组,包含13个数字的列表为_1,它的产品为_2,因为它似乎你想要两个.

奖金

现在我考虑一下.有一种称为滑动的方法可以解决这个问题.但我想它的运行速度和你的scala代码一样慢.至少这会很短:).

content.sliding(13).maxBy(_.reduce(_*_))

(编辑:李大同)

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

    推荐文章
      热点阅读