gpt4 book ai didi

optimization - 为什么我的 Coldfusion 代码现在在字符串处理上快了 100 倍?

转载 作者:行者123 更新时间:2023-12-03 15:29:11 27 4
gpt4 key购买 nike

所以,正如我的标题所说,我有一个 ColdFusion 程序,它过去需要 10 分钟才能在我们的服务器上运行,但现在可以在 中运行。 <15 秒。我很困惑为什么这么简单的程序要花 10 分钟,我和我的老板检查了它以找出 culprit导致速度变慢的代码部分。我们最终成功了 从 10 分钟开始 5-10 秒 运行。

现在我们不确定为什么修复是修复,所以我们想看看是否有人可以向我们解释为什么/如何工作,以便我们可以理解修复,这样我们就可以利用其他程序中的加速.

这个程序的开始是一个查询,它抓取了大约 4800 条记录(没什么了不起的),然后我们遍历这些记录,我们发现这是慢部分。这是我们拥有的内容以及我们为修复它所做的工作的粗略示例。 TextString 设置在靠近查询的顶部到我们返回的字段的标题。

旧代码:

<cfloop>
<CFSET TextString = TextString & DriverID & TabChar & LocalSSN & TabChar & FirstName & CarriageReturn & LineFeed>
</cfloop>

固定代码:
<cfloop>
<CFSET LocalTextString = "">
<CFSET LocalTextString = LocalTextString & DriverID & TabChar & LocalSSN & TabChar & FirstName & CarriageReturn & LineFeed>
<CFSET TextString = TextString & LocalTextString>
</cfloop>

最佳答案

由于字符串在 CF 中的连接方式,您的代码几乎肯定会更快。虽然我不知道 CF 的确切内部结构,但我怀疑将字符串视为不可变的。这意味着每次使用 & 将一个额外的变量连接到 String 时,它都会创建一个新的 String,在末尾包含旧的 String 和新的字符串。
为此,它必须分配内存,随着字符串的增长,内存会越来越多。

有 8 个变量被添加到字符串中,每个变量都在循环中,包括之前版本的字符串,因此您在循环期间分配了 ~4800*8 个字符串。

假设每行的长度为 35 个字符,则字符串的最终大小将为 168k。
这意味着它在运行期间的平均大小是它的一半:84k。
现在,请记住您正在分配字符串 4800*8 次,您使用了多达 3 演出 (4800*8*8400) 的内存来创建 168k 的输出。这意味着 Java 必须进行大量的垃圾收集和额外的工作来为您的代码提供服务。

您更新后的代码在 8 次中有 7 次在 LocalTextString 上工作,相比之下,这会很小,因此您将获得相当大的速度提升。

试试这个版本:

<cfset buffer=ArrayNew()>
<cfset crlf=CarriageReturn & LineFeed />
<cfloop>
<cfset ArrayAppend(buffer,DriverID)>
<cfset ArrayAppend(buffer,TabChar)>
<cfset ArrayAppend(buffer,LocalSSN)>
<cfset ArrayAppend(buffer,TabChar)>
<cfset ArrayAppend(buffer,FirstName)>
<cfset ArrayAppend(buffer,crlf)>
</cfloop>
<cfoutput arrayToList(buffer, "")/>

它构建了一个字符串数组,然后在最后将它们变成一个字符串。您还可以查看 Java 中的 StringBuffer,它执行相同的操作。我上次看的时候,上面的 Array/List 方法最快,但那是 CF 的几个版本。

更新

我对答案中的猜测次数不满意,所以我很想重现这个问题。我使用 5 岁的 Mac 和 CF10 进行测试。
  • 原码:8100ms
  • 改进的原始代码:750ms
  • ArrayAppend 方法:~15ms

  • 如果我在运行测试时将 VisualVM 挂接到 ColdFusion 进程上,我可以看到原始代码在运行过程中占用了几百兆内存。没有我最初的数学建议那么糟糕;我怀疑它每次遍历循环只创建一次大字符串,而不是每个单独的连接一次。但是,它会在每次运行期间触发 2-3 次较小的垃圾回收,这会降低性能。它还在其运行的核心上使用 100% CPU。

    ArrayAppend 代码平均不会触发 GC,您几乎看不到正在使用的内存。

    我不明白为什么原始代码花了这么长时间,但其他因素包括 CPU 速度、可用内存、正在访问的数据库(我使用 MySQL5)、CF 版本等。

    关于optimization - 为什么我的 Coldfusion 代码现在在字符串处理上快了 100 倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20707919/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com