当前位置:  开发笔记 > 编程语言 > 正文

解析子串直接加倍

如何解决《解析子串直接加倍》经验,为你挑选了0个好方法。

如果我有一个字符串,1 2 3并且我确定包含a的子字符串的位置,double我如何直接从子字符串解析它而不创建临时字符串?

例如,我可以这样做System.Double.Parse(str.Substring(0, 1))但会创建一个缓慢且不必要的临时字符串.是否可以直接从原始字符串的一部分解析double?

编辑

Eric Lippert在这里质疑我的动机,说"小弦很便宜".这样做的动机来自于我对int的解析和看到大量的性能提升做同样的事情,因为显然,小字符串不是那么便宜.

这是一个通过临时字符串来修改一系列int的函数:

let lex f (s: string) =
  let rec inside i0 (s: string, i) =
    if i = s.Length then
      f (s.Substring(i0, i-i0) |> System.Int32.Parse)
    else
      let c = s.[i]
      if '0'<=c && c<='9' then
        inside i0 (s, i+1)
      else
        f (s.Substring(i0, i-i0) |> System.Int32.Parse)
        outside (s, i)
  and outside (s: string, i) =
    if i < s.Length then
      let c = s.[i]
      if '0'<=c && c<='9' then
        inside i (s, i)
      else
        outside (s, i+1)
  outside (s, 0)

这需要2.4s到一个字符串的lex 15,625,000 int.

这是一个避免临时字符串的版本:

let lex f (s: string) =
  let rec inside n (s: string, i) =
    if i = s.Length then f n else
      let c = s.[i]
      if '0'<=c && c<='9' then
        inside (10*n + int c - int '0') (s, i+1)
      else
        f n
        outside (s, i)
  and outside (s: string, i) =
    if i < s.Length then
      let c = s.[i]
      if '0'<=c && c<='9' then
        inside 0 (s, i)
      else
        outside (s, i+1)
  outside (s, 0)

这需要0.255秒,比使用临时字符串的解决方案快9倍!

我认为没有理由为什么lexing浮标应该有所不同.因此,通过不提供从子字符串解析浮点数的能力,.NET在表上保留了一个数量级的性能.我做了很多科学计算,经常不得不哄骗大量的数据,特别是在初创公司时,所以我真的不想像这样把性能抛到脑后.

推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有