在Unboxed Vectors上记忆函数会导致它挂起

 游必有方RK 发布于 2023-01-06 17:24

我正在玩Vector和Unboxed Vectors,程序相当简单.我列举了所有只有2,3和5因子的整数.

我以为我会尝试记忆Data.Vector哪个有效并且非常简单.所以我想我会试试Data.Vector.Unboxed.但是,当z是,它会挂起[0..5],但是当z是[0..4],我不知道为什么.两者之间的区别在于5涉及相互递归的调用.

这里出了什么问题?

import Data.Vector.Unboxed as UV

memoisingCandidateUV :: UV.Vector Bool
memoisingCandidateUV = UV.map isCandidateUV z

isCandidateUV :: Int -> Bool
isCandidateUV 0 = False
isCandidateUV n
    | n2r == 0 = n2q == 1 || memoisingCandidateUV UV.! n2q
    | n3r == 0 = n3q == 1 || memoisingCandidateUV UV.! n3q
    | n5r == 0 = n5q == 1 || memoisingCandidateUV UV.! n5q
    | otherwise = False
    where
      (n2q, n2r) = n `quotRem` 2
      (n3q, n3r) = n `quotRem` 3
      (n5q, n5r) = n `quotRem` 5

leftaroundab.. 8

所有未装箱的容器都是深度严格的,这意味着你不能将它们用于懒惰的记忆:在任何元素可以被记忆后访问之前,你必须对所有元素进行评估.

至于为什么会这样:当你在Haskell中有一个正常的懒惰时,它就是带有关于该值现在还没有在NF中的信息的盒子,但为了使它能够执行这段代码.完成之后,框基本上只是指向结果的指针.
在许多情况下,这是一个很好的帮助,但它不是为了免费的内存或性能:通过直接将结果信息直接存储在紧密的数组中,这正是未装箱容器移除的开销.

2 个回答
  • 所有未装箱的容器都是深度严格的,这意味着你不能将它们用于懒惰的记忆:在任何元素可以被记忆后访问之前,你必须对所有元素进行评估.

    至于为什么会这样:当你在Haskell中有一个正常的懒惰时,它就是带有关于该值现在还没有在NF中的信息的盒子,但为了使它能够执行这段代码.完成之后,框基本上只是指向结果的指针.
    在许多情况下,这是一个很好的帮助,但它不是为了免费的内存或性能:通过直接将结果信息直接存储在紧密的数组中,这正是未装箱容器移除的开销.

    2023-01-06 17:25 回答
  • 在这种特定情况下(所有递归调用都是较小的索引,并且n可以从已经计算的向量重建),您可以使用constructN(它迭代地工作而不是依赖于懒惰):

    import Data.Vector.Unboxed as UV
    
    memoisingCandidateUV :: UV.Vector Bool
    memoisingCandidateUV = UV.constructN 100 isCandidateUV
    
    isCandidateUV :: UV.Vector Bool -> Bool
    isCandidateUV vec = result
      where
        n = UV.length vec
    
        result
          |   n == 0 = False
          | n2r == 0 = n2q == 1 || vec UV.! n2q
          | n3r == 0 = n3q == 1 || vec UV.! n3q
          | n5r == 0 = n5q == 1 || vec UV.! n5q
          | otherwise = False
    
        (n2q, n2r) = n `quotRem` 2
        (n3q, n3r) = n `quotRem` 3
        (n5q, n5r) = n `quotRem` 5
    

    2023-01-06 17:25 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有