1

Ok。1,000,000,000 件のレコードを入力として 20 GB のファイルを受け取り、アクセスを高速化するためにある種のインデックスを作成するプログラムを作成することになっています。基本的に、1 bil のレコードを 10 個のバケットと 10 個のサブバケットに分割することにしました。適切なバケットを見つけるために、レコードの 2 つのハッシュ値を計算しています。ここで、サブバケットごとに 1 つずつ、10*10 ファイルを作成します。そして、入力ファイルからレコードをハッシュするときに、100 個のファイルのどれに移動するかを決定します。次に、レコードのオフセットをその特定のファイルに追加します。10,000 レコードのサンプル ファイルでこれをテストしました。このプロセスを10回繰り返しました。100,000 レコード ファイルを効果的にエミュレートします。これには約18秒かかります。これは、1 ビルのレコード ファイルに対して同じことを行うのに永遠にかかることを意味します。とにかく、執筆をスピードアップ/最適化できますか。

import java.io.*;

// PROGRAM DOES THE FOLLOWING

// 1. READS RECORDS FROM A FILE. 
// 2. CALCULATES TWO SETS OF HASH VALUES N, M
// 3. APPENDING THE OFFSET OF THAT RECORD IN THE ORIGINAL FILE TO ANOTHER FILE "NM.TXT"  i.e REPLACE THE VALUES OF N AND M.
// 4.  

class storage
{

        public static int siz=10;
    public static FileWriter[][] f;
}

class proxy
{

    static String[][] virtual_buffer;
    public static void main(String[] args) throws Exception
    {
        virtual_buffer = new String[storage.siz][storage.siz]; // TEMPORARY STRING BUFFER TO REDUCE WRITES


        String s,tes;


        for(int y=0;y<storage.siz;y++)
            {
            for(int z=0;z<storage.siz;z++)
            {
            virtual_buffer[y][z]="";            // INITIALISING ALL ELEMENTS TO ZERO
            }
            }




        int offset_in_file = 0;          

        long start = System.currentTimeMillis();


              // READING FROM THE SAME IP FILE 20 TIMES TO EMULATE A SINGLE BIGGER FILE OF SIZE 20*IP FILE
        for(int h=0;h<20;h++){                

         BufferedReader in = new BufferedReader(new FileReader("outTest.txt"));
         while((s = in.readLine() )!= null)
         {
            tes = (s.split(";"))[0];
            int n = calcHash(tes); // FINDING FIRST HASH VALUE
            int m = calcHash2(tes); // SECOND HASH
            index_up(n,m,offset_in_file); // METHOD TO WRITE TO THE APPROPRIATE FILE I.E NM.TXT
                offset_in_file++;

         }
         in.close();
        }



         System.out.println(offset_in_file);
         long end = System.currentTimeMillis();
         System.out.println((end-start));
    }




    static int calcHash(String s) throws Exception

    {
        char[] charr = s.toCharArray();;
        int i,tot=0;
        for(i=0;i<charr.length;i++)
        {
            if(i%2==0)tot+= (int)charr[i];
        }
        tot = tot % storage.siz;
        return tot;
    }




       static int calcHash2(String s) throws Exception

    {
        char[] charr = s.toCharArray();
        int i,tot=1;
        for(i=0;i<charr.length;i++)
        {
            if(i%2==1)tot+= (int)charr[i];
        }   
        tot = tot % storage.siz;
        if (tot<0)
            tot=tot*-1;
        return tot;
    }


      static void index_up(int a,int b,int off) throws Exception
   {
    virtual_buffer[a][b]+=Integer.toString(off)+"'"; // THIS BUFFER STORES THE DATA TO BE WRITTEN
    if(virtual_buffer[a][b].length()>2000)           // TO A FILE BEFORE WRITING TO IT, TO REDUCE NO. OF WRITES
    {                                                .

    String file = "c:\\adsproj\\"+a+b+".txt";   
    new writethreader(file,virtual_buffer[a][b]);    // DOING THE ACTUAL WRITE PART IN A THREAD.
    virtual_buffer[a][b]="";


    }
    }
}



class writethreader implements Runnable
{
    Thread t;
    String name, data;
    writethreader(String name, String data)
    {
        this.name = name;
        this.data = data;

        t = new Thread(this);
        t.start();
    }

    public void run()
    {
        try{


        File f = new File(name);
        if(!f.exists())f.createNewFile();   
        FileWriter fstream = new FileWriter(name,true);  //APPEND MODE 
        fstream.write(data);
        fstream.flush(); fstream.close();
            }
        catch(Exception e){}
    }
}
4

2 に答える 2

1

Consider using VisualVM to pinpoint the bottlenecks. Everything else below is based on guesswork - and performance guesswork is often really, really wrong.

I think you have two issues with your write strategy.

The first is that you're starting a new thread on each write; the second is that you're re-opening the file on each write.

The thread problem is especially bad, I think, because I don't see anything preventing one thread writing on a file from overlapping with another. What happens then? Frankly, I don't know - but I doubt it's good.

Consider, instead, creating an array of open files for all 100. Your OS may have a problem with this - but I think probably not. Then create a queue of work for each file. Create a set of worker threads (100 is too many - think 10 or so) where each "owns" a set of files that it loops through, outputting and emptying the queue for each file. Pay attention to the interthread interaction between queue reader and writer - use an appropriate queue class.

于 2011-09-26T00:47:03.057 に答える
0

要件全体を破棄して、データベースを使用します。

于 2011-09-26T10:32:29.783 に答える