【问题标题】:Optimize F# string concatenation优化 F# 字符串连接
【发布时间】:2009-06-22 19:49:56
【问题描述】:

我正在构建一次批量插入 4096 条记录的 MySql 查询。实际插入速度非常快,但瓶颈是生成查询。关于优化这个的任何提示?字符串生成当前花费的时间大约是查询的 18 倍。

                    let builder = StringBuilder(524288)
                    Printf.bprintf builder
                        "
                         INSERT INTO %s
                             (`ID`,
                              `Tag`,
                              `Port`,
                              `Excess`,
                              `Return`,
                              `StartDate`,
                              `EndDate`
                              ) 
                          values "
                        x.evaluationstable

                    evaluations
                    |> Seq.iter(fun (e) ->
                        Printf.bprintf builder 
                            " (%d, '%s', '%s', %A, %A, %A, %A), "
                            e.ID
                            e.Tag
                            e.Port
                            e.Excess
                            e.Return
                            (e.StartDate.ToString(x.datetimeformat))
                            (e.EndDate.ToString(x.datetimeformat))
                    )

【问题讨论】:

    标签: string optimization f#


    【解决方案1】:

    尝试使用StringBuilder.AppendFormat 而不是Printf.bprintf。当我在您的问题示例中进行此更改时,我看到了巨大的性能提升(约 80 倍)。

    evaluations
    |> Seq.iter (fun (e) ->
        builder.AppendFormat(
            " ({0}, '{1}', '{2}', {3}, {4}, {5}, {6}), ",
            e.ID,
            e.Tag,
            e.Port,
            e.Excess,
            e.Return,
            (e.StartDate.ToString("MM/dd/yyyy")),
            (e.EndDate.ToString("MM/dd/yyyy"))
        ) |> ignore
    )
    

    【讨论】:

    • 不错。这工作得很好,我看到总速度提高了 10 倍,但这包括打开连接和运行查询。谢谢!
    【解决方案2】:

    我会尽量避免将数据直接嵌入到 SQL 中。使用一系列带参数的准备好的语句,并将这些参数设置为值(不格式化它们)。这样更安全,而且可能效率更高。

    我不确定您是否仍然可以批量执行此操作,而不是在同一事务中的多个单独调用中执行此操作。

    【讨论】:

    • 感谢您的回复。我最初是从一组参数化语句中转换它的,并通过直接多行插入获得了巨大的性能提升。我可能会尝试两者的混合,一种更大的多行参数化类型。我对 F# 相当陌生,所以我对是否有更有效的方法来执行我在这里尝试的字符串 concat 很感兴趣。我确实发现 %A 格式非常昂贵,并且通过不使用它们几乎可以将执行时间减半。
    • 更安全,是的。更有效率,不!每个语句往返到 db 的开销会降低性能。
    • @Robert:这就是使用批处理而不是几个单独调用的重点。假设可以,不会有额外的往返。
    猜你喜欢
    • 1970-01-01
    • 2011-06-12
    • 2017-06-10
    • 2010-09-29
    • 2020-02-29
    • 1970-01-01
    • 2017-03-09
    • 2013-09-24
    • 1970-01-01
    相关资源
    最近更新 更多