F#正确使用序列缓存 [英] F# using sequence cache correctly

查看:96
本文介绍了F#正确使用序列缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Seq.cache与我使函数返回的素数序列一起使用,该素数序列最多包含N(不包括数字1)。我在弄清楚如何将缓存的序列保持在范围内时遇到了麻烦,但是

I'm trying to use Seq.cache with a function that I made that returns a sequence of primes up to a number N excluding the number 1. I'm having trouble figuring out how to keep the cached sequence in scope but still use it in my definition.

let rec primesNot1 n = 
    {2 .. n} 
    |> Seq.filter (fun i -> 
        (primesNot1 (i / 2) |> Seq.for_all (fun o -> i % o <> 0)))
    |> Seq.append {2 .. 2}
    |> Seq.cache

关于如何使用Seq.cache来加快速度的任何想法?目前,它一直在降低作用域,只会降低性能。

Any ideas of how I could use Seq.cache to make this faster? Currently it keeps dropping from scope and is only slowing down performance.

推荐答案

Seq.cache 缓存 IEnumerable< T> 实例,以便序列中的每个项目仅计算一次。不过,就您而言,您要缓存一个函数返回的序列,并且每次调用该函数时,都会得到一个 new 缓存序列,这对您没有任何好处。正如您所概述的那样,我认为缓存并不是解决问题的正确方法;

Seq.cache caches an IEnumerable<T> instance so that each item in the sequence is only calculated once. In your case, though, you're caching the sequence returned by a function, and each time you call the function you get a new cached sequence, which doesn't do you any good. I don't think caching is really the right approach to your problem as you've outlined it; instead you should probably look into memoization.

如果要定义质数小于 n 的函数,而不是定义该函数来定义素数的无限可数序列,那么缓存就更有意义了。看起来更像这样:

If instead of defining a function giving the primes less than n you want to define an infinite enumerable sequence of primes, then caching makes more sense. That would look more like this:

let rec upFrom i =
  seq { 
    yield i
    yield! upFrom (i+1)
  }

let rec primes =
  seq { 
    yield 2
    yield!
      upFrom 3 |>
      Seq.filter (fun p -> primes |> Seq.takeWhile (fun j -> j*j <= p) |> Seq.forall (fun j -> p % j <> 0))
  }
  |> Seq.cache

我没有将这种方法的性能与您的方法进行比较。

I haven't compared the performance of this method compared to yours.

这篇关于F#正确使用序列缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆