大量数据的文件读写问题,有请高手! ( 积分: 100 )

  • 主题发起人 主题发起人 peerson
  • 开始时间 开始时间
P

peerson

Unregistered / Unconfirmed
GUEST, unregistred user!
问题如下:
近日写一个彩票组合小程序,将35选7的全部组合数据写入文件,遇到了读写速度的问题,请各位大富翁指点迷津。
组合所用的源代码,来自creation_zy大富翁的算法,稍作了改动,在此致谢!
//以下过程用于号码组合,code_str:要组合的号码串,形式:"01 02 03 04 05 06 07.....35"
,N:号码总数,M:选号个数,Count:输出总组合数
type
PXCode=^XCode;
XCode=record
searial: Integer;
number: String;
end;
ZCodeArray=array of XCode;
Procedure CNM(const code_str: string;
const N,M:Integer;out Count:Integer);
var
A:array of Integer;
i:Integer;
R : ZCodeArray;
out_file:textfile;
procedure Gen(Level:Integer);
var
j,s:Integer;
begin
if Level=M then
begin
for j:=0 to M-1do
begin
write(out_file,R[R[j].searial].number);
end;
write(out_file,#13+#10);
//分行
Inc(Count);
exit;
end;
if Level=0 then
s:=0
else
s:=R[Level-1].searial+1;
for j:=s to N-M+Leveldo
begin
R[Level].searial:=j;
Gen(Level+1);
end;
end;
begin
Count:=0;
setlength(R,N);
for i:=0 to N-1do
R.number:=copystr(code_str,i*3+1,2)+' ';
if (N<1) or (M>N) or (M<1) then
exit;
assignfile(out_file,'comb_str.txt');
rewrite(out_file);
SetLength(A,N);
for i:=0 to N-1do
A:=i;
Gen(0);
closefile(out_file);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i,count:integer;
ss:string;
begin
ss:='';
for i:=1 to 35do
begin
if i<10 then
ss:=trim(ss+' '+'0'+inttostr(i)) else
ss:=trim(ss+' '+inttostr(i));
end;
CNM(ss,35,7,count);
application.MessageBox('OVER!','MSG',64);
end;

以上代码测试35选7的时候,生成6724520种组合,在关闭卡巴斯基等防病毒软件的监控功能时,本人机器上(AMD 2500+,512M)历时7″,能忍受,但开启防病毒软件的监控,居然奇慢无比,耗时近30″,同样的环境下,其他的彩票软件完成相同的组合,却不受影响,大约3″左右就完成了组合及写入数据表(呜呜,这样大量的数据我真搞不明白如何快速追加到库的:-( )。
请教各位大富翁:1、上述代码该如何优化,以达到不关闭防病毒监控就可以高速写入的目的?
2、如果将输出到文本文件,改为流文件或其他格式文件(可以写入非文本数据),该如何实现才能高速写入?(我用blockwrite(out_file,buffer,3)替换,速度直线下降,慢到不能忍受)
以上问题请高手们指点指点,万分感谢!
 
问题如下:
近日写一个彩票组合小程序,将35选7的全部组合数据写入文件,遇到了读写速度的问题,请各位大富翁指点迷津。
组合所用的源代码,来自creation_zy大富翁的算法,稍作了改动,在此致谢!
//以下过程用于号码组合,code_str:要组合的号码串,形式:&quot;01 02 03 04 05 06 07.....35&quot;
,N:号码总数,M:选号个数,Count:输出总组合数
type
PXCode=^XCode;
XCode=record
searial: Integer;
number: String;
end;
ZCodeArray=array of XCode;
Procedure CNM(const code_str: string;
const N,M:Integer;out Count:Integer);
var
A:array of Integer;
i:Integer;
R : ZCodeArray;
out_file:textfile;
procedure Gen(Level:Integer);
var
j,s:Integer;
begin
if Level=M then
begin
for j:=0 to M-1do
begin
write(out_file,R[R[j].searial].number);
end;
write(out_file,#13+#10);
//分行
Inc(Count);
exit;
end;
if Level=0 then
s:=0
else
s:=R[Level-1].searial+1;
for j:=s to N-M+Leveldo
begin
R[Level].searial:=j;
Gen(Level+1);
end;
end;
begin
Count:=0;
setlength(R,N);
for i:=0 to N-1do
R.number:=copystr(code_str,i*3+1,2)+' ';
if (N<1) or (M>N) or (M<1) then
exit;
assignfile(out_file,'comb_str.txt');
rewrite(out_file);
SetLength(A,N);
for i:=0 to N-1do
A:=i;
Gen(0);
closefile(out_file);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i,count:integer;
ss:string;
begin
ss:='';
for i:=1 to 35do
begin
if i<10 then
ss:=trim(ss+' '+'0'+inttostr(i)) else
ss:=trim(ss+' '+inttostr(i));
end;
CNM(ss,35,7,count);
application.MessageBox('OVER!','MSG',64);
end;

以上代码测试35选7的时候,生成6724520种组合,在关闭卡巴斯基等防病毒软件的监控功能时,本人机器上(AMD 2500+,512M)历时7″,能忍受,但开启防病毒软件的监控,居然奇慢无比,耗时近30″,同样的环境下,其他的彩票软件完成相同的组合,却不受影响,大约3″左右就完成了组合及写入数据表(呜呜,这样大量的数据我真搞不明白如何快速追加到库的:-( )。
请教各位大富翁:1、上述代码该如何优化,以达到不关闭防病毒监控就可以高速写入的目的?
2、如果将输出到文本文件,改为流文件或其他格式文件(可以写入非文本数据),该如何实现才能高速写入?(我用blockwrite(out_file,buffer,3)替换,速度直线下降,慢到不能忍受)
以上问题请高手们指点指点,万分感谢!
 
读写太多,防病毒监控检查太多。
先把它写到数组或内存文件,在一次或多次写到磁盘。
 
用文件流TFileStream或内存流TMemoryStream试试。
 
发现流的追加写入也是很慢的~~~
 
顶出来,高手们赐教一下吧,谢谢了...
 
不要以字符串方式输出,太浪费空间了,改用01数组方式,例如:
a:array[1..35] of 0..1;
 
to AI_Player:
不好意思,初学delphi,不知道01数组该如何使用呢?能给段代码例子吗?谢谢!
 
顶顶顶!不信大富翁们都转业了:-(
 
大富翁,真不像以前了~~~
 
增加写盘的缓存
var
Buf: array[1..524288] of Byte;
(默认值是很小的,此处设置为0.5M)
begin
...
system.SetTextBuf(F, Buf);
{ or SetTextBuf(F, Buf, SizeOf(Buf));
}
...
刚才试了几次,全部小于20″ 最快在13″
 
感谢吴下阿蒙,该法真的有效,增加了缓冲大小后,受防病毒软件的干扰很小,但在大量数据时,需要找到一个合理的值,才能达到理想的效果,再次感谢!!
 
后退
顶部