線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2106
推到 Plurk!
推到 Facebook!

如何加快讀取txt檔的速度!

尚未結案
k804138
一般會員


發表:3
回覆:4
積分:1
註冊:2005-04-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-12-08 08:20:11 IP:218.166.xxx.xxx 未訂閱
      FILE *fp4,*fin4,*fcin4;
      int finish_line;//要做的點數 以下面的例子finish_line=4 
      typedef struct relnode
      {
       int s0,s1;
       float s2;
      }relation;
      relation temp,refer;
      fin4=fopen("D:\\grey\\in.txt","r");
      fp4=fopen("D:\\grey\\out.txt","w");
      int cal_add_num=(finish_line-1)*finish_line;
      for(int i=0;i    其中in.txt裡的資料如下:
0      1      0.793944
0      2      0.665598
0      3      0.698406
1      0      0.782290
1      2      0.755885
1      3      0.664225
2      0      0.650014
2      1      0.764225
2      3      0.924070
3      0      0.677153
3      1      0.663666
3      2      0.886344    refer與temp讀取同一個檔,其中先讀取一次refer,然後在讀取temp(連續讀取),當refer與temp的s0跟s1顛倒相同的時候,將他們的s2將相加然後寫入fp4.    寫完的out.txt為:
0 1 1.576234
0 2 1.315612
0 3 1.375559
1 2 1.520110
1 3 1.327891
2 3 1.810414    但是再執行這一段程式所需要的時間太長(執行過finish_line=267,16小時跑不完),曾經想過要將整個in.txt存進記憶體,因為到後來的資料點數為3千多,要存進3千*(3千-1)個資料,所以怕到時候記憶體會不足,有沒有什麼方式可以達到同樣的效果,並且使執行數度加快.    可能是我寫的方式不是很好,收尋到有找到有人建議使用TStringList,但是我買的書都沒有介紹到,因為沒有例子不會使用.    發表人 - k804138 於 2005/12/08  08:33:09
        
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-12-08 15:53:47 IP:220.130.xxx.xxx 未訂閱
只是建議方法,有需要請自行改寫
unit Unit1;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;    type
  TObj = class(TPersistent)
  public
    s0: Char;
    s1: Char;
    s2: Single;
  end;      TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
  end;    var
  Form1: TForm1;    implementation    {$R *.dfm}    procedure TForm1.Button1Click(Sender: TObject);
var
  T: Cardinal;
  I, Index: Integer;
  AKey: string;
  Obj: TObj;
  F, G, ObjList: TStringList;
begin
  T := GetTickCount;
  if FileExists('C:\IN.TXT') then
  begin
    ObjList := TStringList.Create;
    try
      ObjList.Duplicates := dupIgnore;
      ObjList.Sorted := True;
      F := TStringList.Create;
      try
        F.LoadFromFile('C:\IN.TXT');
        Label1.Caption := 'Source DataCount='   IntToStr(F.Count);    //產生Keyd Objects
        for I := 0 to F.Count-1 do
        begin
          AKey := F[I][1]   F[I][3];
          if not ObjList.Find(AKey, Index) then
          begin
            Obj := TObj.Create;
            Obj.s0 := F[I][1];
            Obj.s1 := F[I][3];
            //這個初值定義不嚴謹,隨此Key出現的位置會有不同//
            Obj.s2 := StrToFloat(Copy(F[I],5,Length(F[I])-4));
            ObjList.AddObject(AKey, Obj);
          end;
        end;    //Process Input Data 
        for I := 0 to F.Count-1 do
        begin
          AKey := F[I][3]   F[I][1];//尋找此Key值之物件
          if ObjList.Find(AKey, Index) then
          begin
            Obj := TObj(ObjList.Objects[Index]);
            Obj.s2 := Obj.s2   StrToFloat(Copy(F[I],5,Length(F[I])-4));
          end;
          //沒有找到具有此Key值之物件,則此筆資料不列入計算.
        end;
      finally
              FreeAndNil(F);
      end;    //Save Data to File
      F := TStringList.Create;
      try
        for I := 0 to ObjList.Count-1 do
          with TObj(ObjList.Objects[I]) do
            F.Add(Format('%s %s .6f', [s0, s1, s2]));
        F.SaveToFile('C:\OUT.TXT');
      finally
        FreeAndNil(F);
      end;        finally    //Free All Keyed Objects
      while ObjList.Count > 0 do
      begin
        ObjList.Objects[0].Free;
        ObjList.Delete(0);
      end;
      FreeAndNil(ObjList);        end;
  end;
  Label2.Caption := 'Elapsed TickCount='   IntToStr(GetTickCount-T);    end;    執行結果資料筆數 131712筆(就你的資料重複複製),執行時間 500ms    其下為輸出資料:    0 1 8586.752930
0 2 7134.373535
0 3 7433.805176
1 0 8715.125977
1 2 8388.548828
1 3 7284.408203
2 0 7305.764648
2 1 8297.096680
2 3 9729.314453
3 0 7665.728516
3 1 7290.617676
3 2 10141.905273    NOTE: 請自行斟酌由字串取值的做法,這裡只就你的資料作簡單實作.
發表人 - jow 於 2005/12/08 16:15:07
k804138
一般會員


發表:3
回覆:4
積分:1
註冊:2005-04-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-12-09 09:57:40 IP:218.166.xxx.xxx 未訂閱
可能我還是程式初學者,你用的語法我不知道是哪種,抱歉. 我當finish_line很小的時候執行也很快,但是當finish_line(=64的時候我執行30分鐘)很大的時候要一直重複開同檔關檔,不知道是不是這邊花不少的時間. 還是我要用二維陣列去存我只是怕最後我要開的陣列[3000][3000],怕會太大.
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-12-10 23:19:50 IP:61.230.xxx.xxx 未訂閱
k804138 您好:    請您澄清以下兩點,以便確認您的問題: 1. in.txt 檔案內的資料,是不是每一行為一個資料點的數據?換言之;是否最多為三千筆資料行? 2. 您說的三千乘以三千減一這個數字是做什麼用的?若資料筆數為 N,那麼為何要有 (N-1) * N 這樣的數字? 7 天天敲鍵盤 v 時時按滑鼠 8
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-12-13 14:50:21 IP:220.130.xxx.xxx 未訂閱
 
unit1.h    //---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include 
#include 
#include 
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TRelNode : TPersistent
{
private:
  AnsiString __fastcall GetKey();
  AnsiString __fastcall GetKey2();
  AnsiString __fastcall GetValStr();
public:
  int s0, s1;
  float s2;
  __property AnsiString Key = {read=GetKey};
  __property AnsiString Key2 = {read=GetKey2};
  __property AnsiString ValStr = {read=GetValStr};
};    class TForm1 : public TForm
{
__published:        // IDE-managed Components
  TButton *Button1;
  TLabel *Label1;
  TLabel *Label2;
  void __fastcall Button1Click(TObject *Sender);
private:        // User declarations
public:                // User declarations
  __fastcall TForm1(TComponent* Owner);
  void __fastcall String2Value(AnsiString Value, int *s0, int *s1, float *s2);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif    unit1,cpp
//---------------------------------------------------------------------------
#include 
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
AnsiString __fastcall TRelNode::GetKey()
{
  AnsiString ret;
  return ret.sprintf("%d %d", s0, s1);
}
//---------------------------------------------------------------------------
AnsiString __fastcall TRelNode::GetKey2()
{
  AnsiString ret;
  return ret.sprintf("%d %d", s1, s0);
}
//---------------------------------------------------------------------------
AnsiString __fastcall TRelNode::GetValStr()
{
  AnsiString ret;
  return ret.sprintf("%d %d %f", s0, s1, s2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::String2Value(AnsiString Value, int *s0, int *s1, float *s2)
{
  int len = Value.Length();
  *s0 = atoi(Value.SubString(1,1).Trim().c_str());
  *s1 = atoi(Value.SubString(3,1).Trim().c_str());
  *s2 = atof(Value.SubString(5,len-4).Trim().c_str());
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
}
//---------------------------------------------------------------------------    void __fastcall TForm1::Button1Click(TObject *Sender)
{
  TStringList *ObjList, *F;
  TRelNode *Obj;
  DWORD T = GetTickCount();
  if(FileExists("C:\\IN.TXT"))
  {
     ObjList = new TStringList();
     try
     {
        ObjList->Duplicates = dupIgnore;
        ObjList->Sorted = true;
        F = new TStringList();
        try
        {
           F->LoadFromFile("C:\\IN.TXT");
           Label2->Caption = "Input Data Count= "   IntToStr(F->Count);
           for(int i=0; iCount; i  )
           {
               AnsiString AKey;
              int Index, s0, s1;
              float s2;
              String2Value(F->Strings[i], &s0, &s1, &s2);
              AKey.sprintf("%d%d", s0, s1);
              if(!ObjList->Find(AKey, Index))
              {
                 Obj = new TRelNode();
                 Obj->s0 = s0;
                 Obj->s1 = s1;
                 Obj->s2 = s2;
                 ObjList->AddObject(AKey, (TObject*)Obj);
              }
           }               for(int i=0; iCount; i  )
           {
              AnsiString AKey;
              int Index, s0, s1;
              float s2;
              String2Value(F->Strings[i], &s0, &s1, &s2);
              AKey.sprintf("%d%d", s1, s0);
              if(ObjList->Find(AKey, Index))
              {
                 Obj = (TRelNode*)ObjList->Objects[Index];
                 Obj->s2 = Obj->s2   s2;
              }
           }
        }
        __finally
        {
                delete F;
        }            F = new TStringList();
        try
        {
                for(int i=0; iCount; i  )
           {
              Obj = (TRelNode*)ObjList->Objects[i];
              F->Add(Obj->ValStr);
           }
           F->SaveToFile("C:\\OUT.TXT");
        }
             __finally
        {
                delete F;
        }         }
     __finally
     {
             while(ObjList->Count>0)
        {
           delete ObjList->Objects[0];
           ObjList->Delete(0);
        }
        delete ObjList;
     }
  }
  Label1->Caption = "Elapsed TickCount = "   IntToStr(GetTickCount() - T);    }
//---------------------------------------------------------------------------    
系統時間:2024-04-28 14:01:48
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!