找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1815|回复: 10

[研讨] 关于一个读文件后字符拆分效率的测试

[复制链接]

已领礼包: 1268个

财富等级: 财源广进

发表于 2014-3-14 15:08:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
源于这个帖子,行数比较多,加上空行 6000 多行
http://bbs.xdcad.net/thread-672899-1-1.html
1 正则表达式一次处理,耗时最长
  1. (defun c:t1 (/ fl lst t0)
  2.   (if (setq fl (getfiled "Select Log File" "" "log" 8))
  3.     (progn
  4.       (setq lst        (XD::List:FromFile fl)
  5.             t0        (get-utime)
  6.       )
  7.       (mapcar '(lambda (x)
  8.                  (XD::String:RegExpS "[^, ]+" x "")
  9.                )
  10.               lst
  11.       )
  12.       (princ (- (get-utime) t0))
  13.     )
  14.   )
  15.   (princ)
  16. )

2 还是正则表达式,加判断提供不同匹配符,有所提升
  1. (defun c:t11 (/ fl lst t0)
  2.   (if (setq fl (getfiled "Select Log File" "" "log" 8))
  3.     (progn
  4.       (setq lst        (XD::List:FromFile fl)
  5.             t0        (get-utime)
  6.       )
  7.       (mapcar '(lambda (x)
  8.                  (if (vl-string-search "," x)
  9.                    (XD::String:RegExpS "[^,]+" x "")
  10.                    (XD::String:RegExpS "[^ ]+" x "")
  11.                  )
  12.                )
  13.               lst
  14.       )
  15.       (princ (- (get-utime) t0))
  16.     )
  17.   )
  18.   (princ)
  19. )


3 用 API 拆分,是前两个的 1/3 时间
  1. (defun c:t2 (/ fl lst t0)
  2.   (if (setq fl (getfiled "Select Log File" "" "log" 8))
  3.     (progn
  4.       (setq lst        (XD::List:FromFile fl)
  5.             t0        (get-utime)
  6.             lst        (mapcar        '(lambda (x)
  7.                            (if (vl-string-search "," x)
  8.                              (xdrx_string_split x ",")
  9.                              (xdrx_string_split x " ")
  10.                            )
  11.                          )
  12.                         lst
  13.                 )
  14.       )
  15.       (princ (- (get-utime) t0))
  16.     )
  17.   )
  18.   (princ)
  19. )

4 用 Lisp 处理,效率最高!
  1. (defun c:t3 (/ fl lst t0)
  2.   (if (setq fl (getfiled "Select Log File" "" "log" 8))
  3.     (progn
  4.       (setq lst        (XD::List:FromFile fl)
  5.             t0        (get-utime)
  6.             lst        (mapcar        '(lambda (x)
  7.                            (if (vl-string-search "," x)
  8.                              (parse x ",")
  9.                              (parse x " ")
  10.                            )
  11.                          )
  12.                         lst
  13.                 )
  14.       )
  15.       (princ (- (get-utime) t0))
  16.     )
  17.   )
  18.   (princ)
  19. )

其它函数
  1. (defun get-utime ()
  2.   (* 86400.0 (getvar "tdusrtimer"))
  3. )
  4. (defun Parse (str delimiter / post strlst stl)
  5.   (and str
  6.        (/= str "")
  7.        (progn
  8.          (setq stl (strlen delimiter))
  9.          (while        (vl-string-search delimiter str)
  10.            (setq post        (vl-string-search delimiter str)
  11.                  strlst        (cons (substr str 1 post) strlst)
  12.                  str        (substr str (+ 1 post stl))
  13.            )
  14.          )
  15.          (setq strlst (reverse (cons str strlst)))
  16.        )
  17.   )
  18.   strlst
  19. )

命令: T1 0.452
命令:
命令: T2
0.14
命令:
命令: T3 0.047
命令:
命令: T1 0.593
命令:
命令: T11 0.452
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 488个

财富等级: 日进斗金

发表于 2014-3-14 17:09:28 | 显示全部楼层
(mapcar '(lambda (x)
                 (if (vl-string-search "," x)
                   (XD::String:RegExpS "[^,]+" x "")
                   (XD::String:RegExpS "[^ ]+" x "")
                 )
               )
              lst
      )


这不公平的,如果不停重复,你RegExp不应该创建和删除那么多次。或者把读进去的按逗号连起来,再一次分开
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-3-14 17:52:23 | 显示全部楼层
本帖最后由 st788796 于 2014-3-14 17:53 编辑
aeo 发表于 2014-3-14 17:09
(mapcar '(lambda (x)
                 (if (vl-string-search "," x)
                   (XD::String: ...

可以一次的,非空格和非逗号连续,匹配符是  [^, ]+ 但这个比分两次要慢得多

应该把 FromFile 改造,空行去掉,这样表长度就减少了

点评

aeo
你没理解我的意思 mapcar 里面至少几百上千次的执行RegExp,你应该把所有文字连成一个字符,仅执行一次RegExp  详情 回复 发表于 2014-3-14 22:39
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2014-3-14 22:39:23 | 显示全部楼层
st788796 发表于 2014-3-14 17:52
可以一次的,非空格和非逗号连续,匹配符是  [^, ]+ 但这个比分两次要慢得多

应该把 FromFile 改造, ...

你没理解我的意思
mapcar 里面至少几百上千次的执行RegExp,你应该把所有文字连成一个字符,仅执行一次RegExp
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-3-14 22:49:22 | 显示全部楼层
本帖最后由 st788796 于 2014-3-14 23:16 编辑
aeo 发表于 2014-3-14 22:39
你没理解我的意思
mapcar 里面至少几百上千次的执行RegExp,你应该把所有文字连成一个字符,仅执行一次R ...

  1. (defun XD::List:FromFile (fn / f l ll)
  2.   (if (setq f (open (findfile fn) "r"))
  3.     (progn
  4.       (while (setq l (read-line f))
  5.         (if l
  6.           (setq ll (cons (strcat l " ") ll))
  7.         )
  8.       )
  9.       (close f)
  10.     )
  11.   )
  12.   ll
  13. )
  14. (defun c:t1 (/ fl lst t0)
  15.   (if (setq fl (getfiled "Select Log File" "" "log" 8))
  16.     (progn
  17.       (setq lst        (XD::List:FromFile fl)
  18.             str        (apply 'strcat lst)
  19.             t0        (get-utime)
  20.       )
  21.       (XD::String:RegExpS "[^, ]+" str "")
  22.       (princ (- (get-utime) t0))
  23.     )
  24.   )
  25.   (princ)
  26. )


命令: (gc)
nil
命令: T1
0.421
命令:
命令:  T1
0.359
命令:
命令:  T1
0.39

比较稳定,字串长了(59xxx)效率也不慢
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 8121个

财富等级: 富甲天下

发表于 2014-3-14 23:22:40 | 显示全部楼层
API的,你试试用 xdrx_string_tok 拆,看看时间多少。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-3-14 23:41:17 | 显示全部楼层
Highflybird 发表于 2014-3-14 23:22
API的,你试试用 xdrx_string_tok 拆,看看时间多少。

还不如 Split 呢,来回通讯耗费了时间
命令: T2
0.546
命令:
命令: T2
0.562
命令:
命令: (gc)
nil
命令: T2
0.764

点评

xdrx_string_split 不需要来回通讯吗?  详情 回复 发表于 2014-3-15 03:35
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-3-15 00:03:58 | 显示全部楼层
再提供一个方法
  1. (defun XD::List:FromFile (fn / f l ll)
  2.   (if (setq f (open (findfile fn) "r"))
  3.     (progn
  4.       (while (setq l (read-line f))
  5.         (if l
  6.           (setq ll (cons (strcat "\"" l "\"" " ") ll))
  7.         )
  8.       )
  9.       (close f)
  10.     )
  11.   )
  12.   ll
  13. )
  14. (defun c:t4 (/ fl lst t0 str)
  15.   (if (setq fl (getfiled "Select Log File" "" "log" 8))
  16.     (progn
  17.       (setq lst        (XD::List:FromFile fl)
  18.             str        (apply 'strcat lst)
  19.             t0        (get-utime)
  20.             lst        (read
  21.                   (strcat "(" (vl-string-translate ",\"" "  " str) ")")
  22.                 )
  23.       )
  24.       (princ (- (get-utime) t0))
  25.     )
  26.   )
  27.   (princ)
  28. )

用时和上面 4 时间几乎相等,但是要修改读文件部分修改至适合使用 vl-string-translate 分割替换

vl-string-translate 是个效率极高的函数 !
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2014-3-15 00:39:59 | 显示全部楼层
用regexp,你首先要把数据传给vbs,传回的还要转换一遍,当然慢.
时间都花在数据交换上了。

vbs 里面直接可以用 split ,你那点字,一刹那的事情。vbs里面用regexp要慢一点,适度越广,速度越慢。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 8121个

财富等级: 富甲天下

发表于 2014-3-15 03:35:56 | 显示全部楼层
st788796 发表于 2014-3-14 23:41
还不如 Split 呢,来回通讯耗费了时间
命令: T2
0.546

xdrx_string_split 不需要来回通讯吗?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-3-15 09:04:17 | 显示全部楼层
Highflybird 发表于 2014-3-15 03:35
xdrx_string_split 不需要来回通讯吗?

不知道 API 中 Split 和 tok 的代码有什么区别?效率基本相当
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-25 00:32 , Processed in 0.377181 second(s), 50 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表