scala 哪种解决方案具有更好的性能:StringBuilder还是String Interpolation-Concatenation

vs3odd8k  于 6个月前  发布在  Scala
关注(0)|答案(3)|浏览(64)

我正在使用Scala将文件写入磁盘。
为了创建将写入文件的整个String,我目前正在迭代我的数据并将所有信息附加到StringBuilder对象。
例如:

val moreData = getMoreData
strBuilder.append(moreData)
strBuilder.append("even more data")
//...
strBuilder.toString

字符串
在操作结束时,我调用StringBuilder的toString方法,并写入Path。
我知道Scala有针对String的编译优化,所以我的问题是:
哪种方法的性能更好。String-Interpolation-Concatenation还是StringBuilder?
这些编译优化是否与StringBuilder有关?换句话说,是否有针对StringBuilder追加操作的优化?

aoyhnmkz

aoyhnmkz1#

字符串插值连接使用StringBuilder来生成其结果。可以进一步优化字符串插值,但就目前而言,它主要是为了表达能力而设计的,而不是性能。如果您知道字符串创建将受到限制,那么应该使用StringBuilder,并且这样做并不难。如果您不知道,或者您知道这不是一个主要问题,字符串插值通常更容易阅读,因此在大多数情况下您应该更喜欢它。

j9per5c4

j9per5c42#

连接多个字符串的最有效方法是使用StringBuilder
但是你的任务不是字符串连接。将多个字符串写入文件的最有效方法是使用好的旧java的FileWriterBufferedWriter

val fw = new FileWriter("foo.out")
val bw = new BufferedWriter(fw)

strings.foreach {
  s =>
    bw.write(s)
}

bw.close()
fw.close()

字符串
如果您需要格式化功能,可以选择用PrintWriter Package BufferedWriter
当然,如果你更喜欢性能而不是代码大小,那么上面的一切都是正确的。

1hdlvixo

1hdlvixo3#

我用VB.NET写了下面的测试程序,字符串连接比插值字符串和stringbuilder都快,这让我有点惊讶。然而,很明显,当进行更多的追加时,stringbuilder将开始获胜,正如最后三个测试所示。

Imports System.Text

Module Module1

    Sub Main()

        Dim sw As New Stopwatch

        sw.Start()

        For i As Integer = 0 To 1000000

            Dim s As String = "DateModified=" & GetString("@auditdatemodified") & ",UserModifiedID = " & GetString("@audituseroptionsid")
            If s = "" Then
                Throw New Exception
            End If

        Next

        sw.Stop()

        Console.WriteLine("concat " & sw.ElapsedMilliseconds)

        sw = New Stopwatch
        sw.Start()

        For i As Integer = 0 To 1000000

            Dim s As String = $"DateModified={GetString("@auditdatemodified")},UserModifiedID = {GetString("@audituseroptionsid")}"
            If s = "" Then
                Throw New Exception
            End If

        Next

        sw.Stop()

        Console.WriteLine("interp " & sw.ElapsedMilliseconds)

        sw = New Stopwatch
        sw.Start()

        For i As Integer = 0 To 1000000

            Dim sb As New StringBuilder
            sb.Append("DateModified=").Append(GetString("@auditdatemodified")).Append(",UserModifiedID = ").Append(GetString("@audituseroptionsid"))
            Dim s As String = sb.ToString
            If s = "" Then
                Throw New Exception
            End If

        Next

        sw.Stop()

        Console.WriteLine("builder " & sw.ElapsedMilliseconds)

        sw = New Stopwatch
        sw.Start()

        For i As Integer = 0 To 1000000

            Dim s As String = "DateModified=" & GetString("@auditdatemodified") & ",UserModifiedID = " & GetString("@audituseroptionsid")
            For j As Integer = 1 To 100
                s = s & GetString("hello world")
            Next
            If s = "" Then
                Throw New Exception
            End If

        Next

        sw.Stop()

        Console.WriteLine("concat many " & sw.ElapsedMilliseconds)

        sw = New Stopwatch
        sw.Start()

        For i As Integer = 0 To 1000000

            Dim s As String = $"DateModified={GetString("@auditdatemodified")},UserModifiedID = {GetString("@audituseroptionsid")}"
            For j As Integer = 1 To 100
                s = $"{s}{GetString("hello world")}"
            Next
            If s = "" Then
                Throw New Exception
            End If

        Next

        sw.Stop()

        Console.WriteLine("interp many " & sw.ElapsedMilliseconds)

        sw = New Stopwatch
        sw.Start()

        For i As Integer = 0 To 1000000

            Dim sb As New StringBuilder
            sb.Append("DateModified=").Append(GetString("@auditdatemodified")).Append(",UserModifiedID = ").Append(GetString("@audituseroptionsid"))
            For j As Integer = 1 To 100
                sb.Append(GetString("hello world"))
            Next
            Dim s As String = sb.ToString
            If s = "" Then
                Throw New Exception
            End If

        Next

        sw.Stop()

        Console.WriteLine("builder many " & sw.ElapsedMilliseconds)

        Console.ReadLine()

    End Sub

    Private Function GetString(s) As String

        Return s

    End Function

End Module

字符串
在我的PC上的结果(最新的核心i7 13系列):

concat 86
interp 150
builder 178
concat many 17607
interp many 45905
builder many 2827

相关问题