String 优化F#字符串连接

String 优化F#字符串连接,string,optimization,f#,String,Optimization,F#,我正在构建一个MySql查询,一次批量插入4096条记录。实际插入相当快,但瓶颈是生成查询。关于优化这个有什么提示吗?目前,字符串生成所花费的时间大约是查询的18倍 let builder = StringBuilder(524288) Printf.bprintf builder " INSERT INTO %s

我正在构建一个MySql查询,一次批量插入4096条记录。实际插入相当快,但瓶颈是生成查询。关于优化这个有什么提示吗?目前,字符串生成所花费的时间大约是查询的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))
                    )

首先,我会尽量避免将数据直接嵌入SQL。使用一系列带参数的准备语句,并将这些参数设置为值(无需格式化)。这样更安全,效率也可能更高


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

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


谢谢你的回复。我最初将其从一组参数化语句转换而来,并通过直接多行插入获得了巨大的性能提升。我可以尝试两者的混合,一种更大的多行参数化类型。我对F#相当陌生,所以我想知道是否有一种更有效的方法来处理我正在尝试的字符串concat。我确实发现%A格式非常昂贵,并且通过不使用它们将执行时间缩短了近一半。是的,更安全。更高效,不!每个语句往返到db的开销都会降低性能。@Robert:这就是使用批处理而不是几个单独调用的要点。如果可以的话,就不会有额外的往返了。很好。这非常有效,我看到总速度提高了10倍,但这包括打开连接和运行查询。谢谢
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
)