It seems that building quotations via <@ @> syntax is painfully inefficient. For example creating a list of integers
let q1 = List.foldBack (fun n acc -> <@ n :: %acc @>) [1..100000] <@ [] @>
Real: 00:00:05.714, CPU: 00:00:05.937, GC gen0: 234, gen1: 47, gen2: 1
Not only does the above code run very slowly but memory performance is also bad
In contrast the following is faster but still poor memory-wise
let q2 =
let (NewUnionCase (cons, [_;NewUnionCase (nil, [])])) = <@ [1] @>
List.foldBack (fun n acc -> Expr.NewUnionCase(cons, [ <@ n @>; acc])) [1..100000] (Expr.NewUnionCase(nil, []))
Real: 00:00:02.352, CPU: 00:00:02.343, GC gen0: 296, gen1: 10, gen2: 0
Finally, using plain old Expr is significantly better (still not as fast as I would have hoped though)
let q3 =
let (NewUnionCase (cons, [_;NewUnionCase (nil, [])])) = <@ [1] @>
List.foldBack (fun n acc -> Expr.NewUnionCase(cons, [ Expr.Value(n, typeof<int>); acc])) [1..100000] (Expr.NewUnionCase(nil, []))
Real: 00:00:00.370, CPU: 00:00:00.375, GC gen0: 8, gen1: 3, gen2: 0