在F#中使用StringBuilder是否正确? [英] Is using a StringBuilder a right thing to do in F#?

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

问题描述

StringBuiler是一个可变对象,F#鼓励尽可能多地使用不变性.因此,应该使用转换而不是变异.在F#中构建字符串时,这是否适用于StringBuilder?是否有F#不变的替代品?如果是这样,那么这种替代方法有效吗?

StringBuiler is a mutable object, F# encourages employing immutability as much as possible. So one should use transformation rather than mutation. Does this apply to StringBuilder when it comes to building a string in F#? Is there an F# immutable alternative to it? If so, is this alternative as efficient?

代码段

推荐答案

我认为在F#中使用StringBuilder非常好-sb.Append返回StringBuilder的当前实例这一事实意味着它可以轻松实现与fold函数一起使用.即使这仍然是必须的(对象已突变),但是当您不公开对StringBuilder的引用时,它也非常适合功能样式.

I think that using StringBuilder in F# is perfectly fine - the fact that sb.Append returns the current instance of StringBuilder means that it can be easily used with the fold function. Even though this is still imperative (the object is mutated), it fits reasonably well with the functional style when you do not expose references to StringBuilder.

但是,同样地,您可以使用String.concat构造一个字符串列表并将其连接-这几乎与使用StringBuilder一样高效(它速度较慢,但​​幅度不大-并且比使用cc串联字符串要快得多) +)

But equally, you can just construct a list of strings and concatenate them using String.concat - this is almost as efficient as using StringBuilder (it is slower, but not much - and it is significantly faster than concatenating strings using +)

因此,列表可以为您提供类似的性能,但是它们是不可变的(并且可以很好地并发使用)-如果您通过算法构建字符串,它们将是一个很好的选择,因为您可以将字符串追加到列表的前面-这是对列表的非常有效的操作(然后反转字符串).另外,使用列表表达式为您提供了一种非常方便的语法:

So, lists give you similar performance, but they are immutable (and work well with concurrency etc.) - they would be a good fit if you were building string algorithmically, because you can just append strings to the front of the list - this is very efficient operation on lists (and then reverse the string). Also, using list expressions gives you a very convenient syntax:

// Concatenating strings using + (2.3 seconds)
let s1 = [ for i in 0 .. 25000 -> "Hello " ] |> Seq.reduce (+)
s1.Length

// Creating immutable list and using String.concat (5 ms)
let s2 = [ for i in 0 .. 25000 -> "Hello " ] |> String.concat ""
s2.Length

// Creating a lazy sequence and concatenating using StringBuilder & fold (5 ms)
let s3 = 
  seq { for i in 0 .. 25000 -> "Hello " }
  |> Seq.fold(fun (sb:System.Text.StringBuilder) s -> 
      sb.Append(s)) (new System.Text.StringBuilder())
  |> fun x -> x.ToString()
s3.Length

// Imperative solution using StringBuilder and for loop (1 ms)
let s4 = 
  ( let sb = new System.Text.StringBuilder()
    for i in 0 .. 25000 do sb.Append("Hello ") |> ignore
    sb.ToString() )
s4.Length

时间是在F#Interactive中使用#time在我相当快的工作机上测量的-很有可能在发布版本中会更快,但我认为它们具有代表性.

The times were measured on my, fairly fast, work machine using #time in F# Interactive - it is quite likely that it would be faster in release build, but I think they are fairly representative.

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

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