Is it possible to use immutable collections in this case?

236 Views Asked by At

I have translated a code from python to F# but I wished to use a more idiomatic syntax. I think that there are two big obstacles

  • poor performance (consider that n is very big)
  • not powerful enough abstractions

The current (working) code I have is

let valuefolded =
    System.Collections.Generic.List(
        [0..( (n - (offset % input.Length) - 1) / input.Length)]
        |> List.fold
            (fun acc _ -> List.append acc input)
            (input
            |> List.skip (offset % input.Length)))
for repeat in [0..99] do  
    let mutable acc = 0
    for i in ([0..(n-1)] |> List.rev) do
        valuefolded.[i] <- Math.Abs(acc + valuefolded.[i]) % 10
        acc <- valuefolded.[i]

(fyi on my laptop with actual data it takes about a minute)

Now there are two mutable that I wish to make immutable, if it is possible and if it makes sense.

  1. the mutable acc (this is done, see below)
  2. the System.Collections.Generic.List wrapper
1

There are 1 best solutions below

1
On

Looks like you use Generic.List solely to have a collection you can access by index. You can use built-in Array instead. Here's the code

let valuefolded =        
        [0..( (n - (offset % input.Length) - 1) / input.Length)]
        |> List.fold
            (fun acc _ -> List.append acc input)
            (input
            |> List.skip (offset % input.Length))
        |> Array.ofList

Also, I encourage you to check it yourself but my observation for the following parameters

let offset = 1
    let input = [1..10000000]
    let n = 3

show that it performs faster than original version.