32 | 让人又恨又爱的字符串操作
该思维导图由 AI 生成,仅供参考
性能优化技巧的背后
理念一:处理请求要短、平、快
- 深入了解
- 翻译
- 解释
- 总结
OpenResty 中字符串操作的性能优化技巧是本文的重点。作者首先强调了性能优化的重要性,并提出了处理请求要短、平、快以及避免产生中间数据的两个重要理念。文章详细讲解了字符串在 Lua 中的不可变性质,以及对字符串进行拼接操作时可能产生的临时字符串,并给出了使用 table 进行优化的示例代码。此外,作者还提到了使用 `string.sub` 函数可能产生临时字符串的问题,并给出了使用 `string.byte` 和 `string.char` 函数来避免临时字符串生成的替代方案。通过具体的示例代码和优化方法,读者可以了解在 OpenResty 中进行字符串操作时的性能优化技巧,对于提升代码性能具有一定的指导意义。文章还提到了利用 SDK 对 table 类型的支持,以及在 `ngx.say`、`ngx.print` 、`ngx.log`、`cosocket:send` 等 API 中使用 table 作为参数来优化字符串拼接的方法。最后,读者被鼓励思考并分享自己的答案和感想,以及将文章分享给朋友一起学习和交流。整体来说,本文通过深入的技术讲解和实用的示例代码,帮助读者快速了解 OpenResty 中字符串操作的性能优化技巧。
《OpenResty 从入门到实战》,新⼈⾸单¥59
全部留言(10)
- 最新
- 精选
- 林中木温老师,请教一个很困扰的问题: 根据你的指点,要尽量少用 .. 字符串拼接,特别是在代码热区 但是我在处理数据库访问时,需要动态构建sql语句(在语句中插入变量),这应该是非常常见的使用场景,但这个需求,我目前感觉字符串拼接是最简单办法了,其他我真的想不到即简单又高性能的办法。 另外我现在想用OR做一个web项目,但做起来很痛苦啊,主要是没找到成熟的框架,需要自己造很多轮子,就比如说上面的数据库操作问题(没找到可以动态构建sql语句、连贯操作的类库),在web框架上有什么好的可以推荐吗? 等候你的高见! 恳请多多指点。
作者回复: 可以先用火焰图或者其他工具分析下,看 sql 语句的拼接是否是系统的瓶颈,如果不是,自然没有优化的必要性。如果是的话,可以利用数据库的 `prepare` 语句来做优化,也可以用数组的方式来做拼接。 OpenResty 现在确实没有好用的框架,lor、香草这两个可以尝试下。
2019-09-1022 - HelloBug温铭老师,发现需要GC 操作的会是比较耗时的,可以介绍下GC操作的场景吗?
作者回复: 一般是在处理完比较大的对象之后,需要手工 GC 一下。比如字符串对象有几十兆,处理完得到结果之后,手工调用collectgarbage一下。
2019-08-181 - helloworld作业题: ngx.log(ngx.ERR, "Hello ", "world", "!") 另外我测试字符串10个a的拼接和1个a的拼接所用时间是一个数量级的,性能基本没变化。 还有一个就是我测试ngx.say(table)的性能比先table.concat拼接,再ngx.say打印拼接后的字符串的性能要低一倍,测几次都是这个结果,这个是什么原因呢
作者回复: 能给下你测试的代码吗?
2019-08-0721 - Shliesce作业题: local t = {} t[1] = "hello " t[2] = "world " t[3] = "!" ngx.log(ngx.ERR, t[1], t[2], t[3])
作者回复: ngx.log(ngx.ERR, 'hello', ' world', '!') 是更简单的方式,你可以试下
2019-08-12 - wusiration作业题1:当字符串由"a"变成"aaaaaaaaaa"时,代码用时0.007000207901001,性能基本没有差别,因为指向的是同一个字符串,只不过是字符串的内容发生了变化; 作业题2: resty -e ' local helloworld = {"Hello", "World", "!"} helloworld = setmetatable(helloworld, { __tostring = function(t) return string.format("%s %s %s", t[1], t[2], t[3]) end }) ngx.log(ngx.WARN, helloworld) '
作者回复: ngx.log是可以直接跟变参的,这一点文档中并没有写的很明确: ngx.log(ngx.WARN, 'hello ', 'world', '!') 这种是最简单的。
2019-08-07 - helloworldlocal ok, err = red:connect("127.0.0.1", 6379) if not ok then ngx.say("failed to connect: ", err) red:close() -- 老师,我看到有写项目代码里在这里加上这句,有必要吗? return end
作者回复: 我觉得没必要,都没有连接上,close 也没啥意义。
2019-08-07 - Rye温老师,听说string.format的消耗大效 率低,不知道具体是什么原因,有什么好的字符串模板方案么?
作者回复: 我都是用数组的方式自己拼接,比较笨的方法
2019-08-07 - helloworld老师,代码在这里,就是用的你文章中的代码: 测试ngx.say(table)的性能比先table.concat拼接,再ngx.say打印拼接后的字符串的性能要低一倍的问题。 local begin = ngx.now() local t = {} local index = 1 for i = 1, 100000 do t[index] = "a" index = index + 1 end --local s = table.concat(t, "") -- 测试1 --ngx.say(s) -- 测试1 用时:0.003000020980835 ngx.say(t) -- 测试 2 用时:0.01200008392334 ngx.update_time() ngx.say(ngx.now() - begin) 这次又测了一遍,貌似低了三四倍。2019-08-1911
- 宝仔思考题:如果新增的字符串是10个a,性能变化不大。但是如果是直接字符串拼接的方式,那性能差距就大了2020-02-03
- 许童童新增的字符串是 10 个 a 的长度,个人分析,不会有什么性能差异,因为10个a这个字符串一但分配在内存中,在下一次GC前,都是指向这个相同的内存地址,并没有开辟新的内存空间。2019-08-07