精易论坛

标题: 【优化&道歉】超快!替换十万个字符仅需13秒??! [打印本页]

作者: StarAdmire    时间: 2022-10-22 01:39
标题: 【优化&道歉】超快!替换十万个字符仅需13秒??!
本帖最后由 mortalisam 于 2022-10-22 08:15 编辑

【优化&道歉】超快!替换十万个字符仅需13秒??!

道歉声明:
各位易友最近应该都关注到了这样一篇帖子吧
【首发】超快!替换十万个字符只需要7秒!!!!
https://125.confly.eu.org/forum.php?mod=viewthread&tid=14749933
(出处: 精易论坛)
甚至还被官方转发了,也是非常的火热啊
但,这篇帖子越火我良心越过意不去,应该有些人看出来了,如果我只是进行文本替换操作那我无需多线程替换,计次循环足矣,因为有进出许可证限制着


原因也很简单,我发表的这篇帖子并不是最优解,也并不是最初的思路,我最初的思路很复杂,但是(从理论上讲)很完善,但碍于技术和时间问题,我选择了将就,将原思路简化,再在原贴上混了一点水分,本以为并不会多受关注,谁知火了


起初我还并没有意识到这有什么,直到我发现这篇帖子的源码中有几处的bug,以及我最初的思路其实是可以完善下去的,我良心疼,那时候巴不得删帖,但可惜不行
所以我只能在周末的时候,尽可能赶工写出来我最初思路的完善,就当作是对我自己的宽恕吧,
对不起,但这篇帖子所有数据从实,无任何夸张成分
源码我尽可能表明了思路,感谢大家的支持和谅解,非常感谢
演示&介绍:

(PS:上篇帖子属实夸张化了,看似十万个字符,其实真正需要进行替换的只有几百个?因为生成随机文本所生成的字符说到底也就那几个)


原字符(#常量2):(代码生成随机的10万个字符实在太慢了,所以我干脆手动输入,我把宪法啥的都给粘贴下来了)

(一共100000整的)



实际所需替换字符(预计):5万~8万左右?含特殊字符,大小写字母,中文字符等

示例:


开始时间:2022年10月22日1时3分39秒
结束时间:2022年10月22日1时3分53秒
备注:此为未限制线程池上限所花时间,如果限制时间将会被延长
所用时间:14秒


优化:
1.允许限制线程池上限,防止奔溃
2.自动处理重复的欲替换文本
3.保证线程全部结束后才返回,不会出现残留
(PS:保留多线程操作,原因说实话我也不知道,但多线程操作确实比直接子文本替换快很多)

提醒:
此次更新使得批量操作更加依赖于懒人模块v1.3,请自行下载谢谢  
附件免费下载:
https://wwn.lanzouv.com/iUXyI0ec5i7c


作者: Sunnnny    时间: 2022-10-22 09:18
前排学习,支持一下
作者: sinewtec    时间: 2022-10-22 09:30
发布原创作品,精易因你更精彩
作者: 西瓜大大    时间: 2022-10-22 09:39
什么使用场景?
作者: StarAdmire    时间: 2022-10-22 09:46
西瓜大大 发表于 2022-10-22 09:39
什么使用场景?

需要替换的文本又多又杂,对小文本也可以达到提速效果
作者: 菜鸟小杰    时间: 2022-10-22 10:16
对象了解一下
作者: 逆天魔魂    时间: 2022-10-22 10:57
加入许可证其实就是单线程执行,没必要使用多线程了。
作者: 逆天魔魂    时间: 2022-10-22 11:00
逆天魔魂 发表于 2022-10-22 10:57
加入许可证其实就是单线程执行,没必要使用多线程了。

可以看看线程会不会因为超时被强制结束
作者: q1512960733    时间: 2022-10-22 11:16
支持开源精神
作者: lfcliu    时间: 2022-10-22 11:37
6666666666666666666
作者: 794229345    时间: 2022-10-22 13:02
支持开源精神

作者: 福仔    时间: 2022-10-22 14:07
想要效率就不能用易语言提供的文本处理命令, 需要自己实现, 子文本替换这个功能单个替换还行, 替换多个的话, 效率就严重低下
给你个思路, 能不能实现就看你了
1. 先预先分配替换后的文本需要的尺寸, 这个尺寸只能大概的计算, 在使用的过程中每次拷贝数据过去都需要判断尺寸是否足够存放, 不够就重新分配
        比如把 a 替换成 b, 那就根据b的长度减去a的长度的差量 乘以一个可能替换的次数, 这样就得出一个差值
        或者嫌麻烦就直接原文本尺寸 * 2, 不计算
2. 逐个字节循环需要替换的文本, 128以下一个字节增加, 128或128以上两个字节增加
        循环内就判断所有需要替换的文本, 这里需要按指针来操作, 不然文本比较用易语言的话, 需要转换文本, 这个影响效率
        使用c系列的文本比较函数, strncmp() 比较N个字符
3. 如果循环到的这个字节不需要匹配, 那就把这个字节拷贝到你申请的缓冲区内
        如果循环匹配到这个字节需要替换, 那就把替换的文本拷贝到你申请的缓冲区内
        每次拷贝数据都需要判断缓冲区是否足够存放, 不够就需要重新分配空间
4. 循环走完后, 你的缓冲区就是替换好的结果, 基本没有多少次内存申请和释放的操作
        加入是1万个字节的文本, 需要替换100个文本, 最差的情况就是, 10000 * 100 次循环, 就是每次被替换的文本都是数组里的第100个
        
如果是易语言的子文本替换, 他内部怎么实现我也不清楚, 不知道会分配多少次内存
但是 xxx = 子文本替换() 至少会有一次申请内存和释放内存, 如果是100个文本需要替换, 那循环一次就需要申请100次内存+释放100次内存所以, 我这个方案就是减少申请内存和释放内存的操作, 循环次数应该也算是有优化

伪代码
欲分配内存 = 申请内存()
索引 = 0 ' 文本指针索引, 当前处理哪个字节, 这里按从0开始处理, 这个只是个伪代码
判断循环(文本指针[索引] != 0)
{
    计次循环(替换的数组)
    {
        如果相等 strncmp
            替换成 = 记录要替换成什么文本的文本指针
            跳出循环
    }

    判断内存是否够存放()

    判断 替换成 != 0
        拷贝内存(欲分配内存 + n,  替换成) 这个欲分配内存需要跳转指针位置, 每次加入指针都增加加入的尺寸, 这里就简单演示一下
    否则
        拷贝内存(欲分配内存 + n,  文本指针[索引])
    索引 = 索引+1 '继续下一个字节循环
}


作者: lfcliu    时间: 2022-10-22 16:21
我来测试下看看
作者: 深圳梦    时间: 2022-10-22 17:12
支持开源~!感谢分享
作者: shuaier    时间: 2022-10-22 19:00
支持开源~!感谢分享
作者: wjswzj0    时间: 2022-10-23 16:46
支持开源~!感谢分享
作者: 明天自然醒    时间: 2022-10-31 14:12
.版本 2
.支持库 e2ee
.支持库 spec

.子程序 子程序1
.局部变量 文本, 文本型
.局部变量 关键字数组, 文本型, , "0"
.局部变量 替换数组, 文本型, , "0"
.局部变量 过滤器, 文本过滤器
.局部变量 过滤后文本, 文本型
.局部变量 t, 整数型
.局部变量 测试文本, 文本型


文本 = “·支持本地调用扩1@#$%^&*()23展,可以直接对接无人直142sdasda播游戏·解析了文字消息、进入asfasd房间、收到礼物、表情·使用超级编辑框丰富各个消息颜色类型”

测试文本 = 批量生成 (文本, 700)
写到文件 (取运行目录 () + “\text.txt”, 到字节集 (测试文本))

调试输出 (“原文长度”, 取文本长度 (测试文本))

文本_逐字分割 (测试文本, 关键字数组)
.计次循环首 (取数组成员数 (关键字数组), )
    加入成员 (替换数组, “A”)
.计次循环尾 ()

t = 取启动时间 ()

过滤器.创建 (关键字数组, 替换数组)
过滤后文本 = 过滤器.过滤 (测试文本)

调试输出 (“替换后长度”, 取文本长度 (过滤后文本))
调试输出 (取启动时间 () - t)

写到文件 (取运行目录 () + “\new.txt”, 到字节集 (过滤后文本))

.子程序 批量生成, 文本型
.参数 文本, 文本型
.参数 次数, 整数型
.局部变量 unit, 字节集
.局部变量 data, 字节集

unit = 到字节集 (文本)
.计次循环首 (次数, )
    data = data + unit + { 13, 10 }
.计次循环尾 ()
返回 (到文本 (data))

.子程序 __启动窗口_创建完毕

子程序1 ()

作者: zhf130    时间: 2022-11-20 23:14
支持开源~!感谢分享
作者: 小布仕奇    时间: 2022-12-16 12:21
666666666666666666
作者: 小布仕奇    时间: 2022-12-16 14:48
6666666666666666
作者: Wz613613    时间: 2022-12-22 09:00
66666666666666666666666666666
作者: wolfpack    时间: 2024-6-8 10:45





欢迎光临 精易论坛 (https://125.confly.eu.org/) Powered by Discuz! X3.4