哪种解决方案性能更好:StringBuilder 或 String Interpolation-Concatenation

问题描述 投票:0回答:3

我正在使用 Scala 将文件写入磁盘。

为了创建将写入文件的整个字符串,我当前正在迭代数据并将所有信息附加到 StringBuilder 对象。

例如:

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

在操作结束时,我调用 StringBuilder 的 toString 方法,并写入 Path。

我知道 Scala 对字符串有编译优化,所以我的问题是:

哪种方法性能更好。字符串插值连接还是 StringBuilder?

这些编译优化与 StringBuilder 有某种关系吗?换句话说,StringBuilder追加操作有优化吗?

string scala stringbuilder string-interpolation
3个回答
6
投票

字符串插值串联使用

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


1
投票

连接多个字符串的最有效方法是使用

StringBuilder

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

FileWriter
BufferedWriter
:

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

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

bw.close()
fw.close()

如果您需要格式化功能,您可以选择用

BufferedWriter
包裹
PrintWriter

当然,如果您更看重性能而不是代码大小,那么以上所有内容都是正确的。


0
投票

我在 VB.NET 中编写了以下测试程序,令我有点惊讶的是,字符串连接比插值字符串和字符串生成器都快。然而,显然,当进行更多附加操作时,字符串生成器将开始获胜,如最后三个测试所示。


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

我的电脑(最新的酷睿 i7 13 系列)上的结果:

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

© www.soinside.com 2019 - 2024. All rights reserved.