首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在nim中加速将文本截断到特定的字数?

如何在nim中加速将文本截断到特定的字数?
EN

Code Review用户
提问于 2022-07-02 15:23:53
回答 1查看 37关注 0票数 0

我有一个web应用程序,作为它的一部分,我必须定期发送数据库中记录的“概述”,其中包含描述的简短摘要--该记录的文本。

代码应该做什么:

  1. 使用HTML字符串
  2. 删除HTML括号,以便只保留文本
  3. 把它切成SHORT_DESCRIPTION_WORD_COUNT单词
  4. 如果有超过SHORT_DESCRIPTION_WORD_COUNT的单词,添加“.”在最后

我目前的实现如下:

代码语言:javascript
复制
import std/[strutils, strformat, htmlparser, xmltree, enumerate]

const SHORT_DESCRIPTION_WORD_COUNT: int = 40

proc truncate*(text: string): string =
  let cleanedString = text.parseHtml().innerText
  let splitString = cleanedString.split(" ")
  
  if splitString.len() <= SHORT_DESCRIPTION_WORD_COUNT:
    result = cleanedString
  else:
    result.add(splitString[0..SHORT_DESCRIPTION_WORD_COUNT-1].join(" "))
    result.add("...")

查看一些英勇的数据,我确定这个过程占用了相当长的时间,并且会从速度性能优化中得到一些好处。

不过,我很想知道该怎么做。我相信这里的强化步骤是清理HTML,然后拆分字符串,我不知道如何避免这些步骤。

EN

回答 1

Code Review用户

回答已采纳

发布于 2022-07-02 15:23:53

在与亚戴尼科就尼姆的不和进行了一段时间的磋商后,这里有一个重大的改进,还有几个小的改进:

的主要改进:使用拆分迭代器

我使用拆分proc,并将字符串的seq分配到一个变量中进行迭代。当您可以使用拆分迭代器时,这是浪费的。

由于您仍然需要跟踪您在何时点击SHORT_DESCRIPTION_WORD_COUNT时所处的单词,所以您可以使用std/enumerate,这比在循环中编写var i=0和手动递增要好。

代码语言:javascript
复制
proc truncate_breakfor_enumerate*(text: string): string =
    let cleanedString = text.parseHtml().innerText

    for i, str in enumerate(cleanedString.split(" ")):
        result.add(" " & str)
        if i >= SHORT_DESCRIPTION_WORD_COUNT:
            result.add("...")
            break   

小改进:预先分配字符串

这对于添加更长字符串的场景非常重要。将字符串预先分配到大致正确的大小可以减少总体所需的内存分配数。也就是说,如果当您向字符串添加子字符串时,字符串的大小超过了它的大小,那么就需要在其他地方复制它。您可以使用newStringOfCap来完成这个任务。

如果您开始拥有相当数量的文本(>5000字符),而且即使这样,改进也是微不足道的,这甚至会开始起作用。

代码语言:javascript
复制
proc truncate_breakformemoryalloc*(text: string): string =
    let cleanedString = text.parseHtml().innerText
    result = newStringOfCap(400) # <-- The important bit

    for i, str in enumerate(cleanedString.split(" ")):
        result.add(" " & str)
        if i >= SHORT_DESCRIPTION_WORD_COUNT:
            result.add("...")
            break   

我的结果是,通过一个普通文本的基准测试和另一个更人工的基准来运行这些基准,其中有50个字符以上的单词:

代码语言:javascript
复制
name ......................................... min time      avg time    std dv   runs
truncate classic ............................. 0.046 ms      0.053 ms    ±0.004  x1000
truncate_breakfor_enumerate................... 0.021 ms      0.023 ms    ±0.001  x1000
truncate_breakfor_enumerate_memoryalloc ...... 0.021 ms      0.025 ms    ±0.004  x1000
truncate classic long ........................ 0.050 ms      0.082 ms    ±0.019  x1000
truncate_breakfor_enumerate long ............. 0.036 ms      0.040 ms    ±0.007  x1000
truncate_breakfor_enumerate_memoryalloc long ..0.035 ms      0.038 ms    ±0.004  x1000

对于任何目的,这两个版本都应该做得很好。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/277814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档