I am trying to think of a way of how to improve speed of my program and one of the parts is anagram generation. Would the async features help in this case or there is another technique of manipulating strings?
let anagramWords = [|"rolex";"viagra";"win";"free";"cash";"grand";"prize";
"nude";"porn";"casino";"lottery";"spins";"sex";"gold"; "buy"; "clearance";
"business"; "biz"; "money"; "opportunity"; "earn"; "extra"; "potential"; "sleep"; "discount";
"bargain"; "credit"; "affordable"; "loans"; "mortages"; "quote"; "dollars"; "invest"; "investment";
"bitcoin"; "silver"; "save"; "unsecured"; "pennies"; "million"; "billion";"bureaus";"stock";
"bankruptcy"; "eliminate"; "debt"; "billing"; "iphone"; "selling"; "obligation";"trial";
"vacation"; "winner";"membership"; "preview"; "sample"; "priority"; "website"; "gift"; "gifts";
"present"; "deal"; "fantastic"; "outstanding"; "values"; "act"; "lifetime"; "urgent"|]
let rec distribute e = function
| [] -> [[e]]
| x::xs' as xs -> (e::xs)::[for xs in distribute e xs' -> x::xs]
let rec permute = function
| [] -> [[]]
| e::xs -> List.collect (distribute e) (permute xs)
let genAnagrams word =
word
|>List.ofSeq
|>permute
|> List.map (fun x -> String(x |> Array.ofList))
|> Seq.ofList
|> Seq.toList
One very simple way to make this a bit faster is to make
permuteuse arrays instead of lists and useArray.Parallel.collectinstead ofList.collect. Even with the inefficiency of taking the head off an array, it becomes about 30% faster for me for a word of 10 characters.