本帖最后由 嫂子 于 2026-5-4 22:03 编辑
原帖:
关于结构体字节集转换的效率问题_精易论坛
分析:
通过原帖得知 读取逻辑是
跳过4字节 读取 4个无符号短整 4个整 然后跳过4字节
实操思路:
第一次 原帖思路
按照原帖逻辑 跳过4字节 然后 直接将8个数组 组合一个结构体 结构体最后加一个成员 x 整数型 刚好填补 每次跳过4字节。
逐行读取写出 速度2s
第二次 优化读取
改成批量读取 发现 最后一个结构没有了最后的4字节导致失败
灵机一动 大腿一拍 尼玛被原帖带歪了
文件本质结构: 4字节+24字节(要的数据) +4字节+24字节(要的数据)
遂改结构成 x 整数+原先的8成员。完美用x覆盖未知的4字节(大概是头部信息之类的)
一次性读取 耗时只需要2ms了。剩下逐行写出成为了瓶颈 总耗时700ms
第三次 优化写出
既然读取已经完美了,写出的优化自然是 内存拼接 一次性写出了。
使用stringbuilder 1M缓冲区 组合后 一次性写出
结果:89ms
代码如下:
结构体:
[Delphi] 纯文本查看 复制代码 TV = record
unknown: Integer;
v1, v2, v3, v4: Word;
V5, v6, v7, v8: Integer;
end;
操作代码:
[Delphi] 纯文本查看 复制代码 procedure TForm1.Button1Click(Sender: TObject);
var
Bf: array of Tv;
begin
var St := TStopwatch.StartNew; // 启动计时
var Sr := TFileStream.Create('D:\Download\xx\xx.dat', fmOpenRead); // 原始文件
var sb := Tstringbuilder.Create(1024 * 1024); // SB缓冲区1M
var MaxCount: Int64 := Sr.Size div 28; // 算出总记录数
Setlength(Bf, MaxCount); // 直接给数组申请缓存
sr.ReadBuffer(bf[0], MaxCount * 28); // 一次性全部读取
for var i := 0 to MaxCount - 1 do // 挨个塞入Sb
begin
var v := bf;
SB
.Append(v.v1)
.Append(#9)
.Append(v.v2)
.Append(#9)
.Append(v.v3)
.Append(#9)
.Append(v.v4)
.Append(#9)
.Append(v.v5)
.Append(#9)
.Append(v.v6)
.Append(#9)
.Append(v.v7)
.Append(#9)
.Append(v.v8)
.Append(#13#10);
end;
// 最后一次性写出
Tfile.WriteAllText('结果.txt', sb.ToString);
sr.Free; // 释放原始文件流
sb.Free; // 释放sb
st.Stop; // 停止计时
memo1.Lines.Add(st.ElapsedMilliseconds.ToString + 'ms');
end;
|