2016-11-20 5 views
0

私は、ホテルのデータについては、以下のモデルを持っているマルチスレッドを使用してメソッド操作を高速化できますか?

public class HotelData { 

    private String name; 
    private String address; 
    private String stars; 
    private String contact; 
    private String phone; 
    private String uri; 


    public HotelData(String name, String address, String stars, String contact, String phone, String uri) { 
     this.name = name; 
     this.address = address; 
     this.stars = stars; 
     this.contact = contact; 
     this.phone = phone; 
     this.uri = uri; 
    } 

    public HotelData() { 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getAddress() { 
     return address; 
    } 

    public void setAddress(String address) { 
     this.address = address; 
    } 

    public String getStars() { 
     return stars; 
    } 

    public void setStars(String stars) { 
     this.stars = stars; 
    } 

    public String getContact() { 
     return contact; 
    } 

    public void setContact(String contact) { 
     this.contact = contact; 
    } 

    public String getPhone() { 
     return phone; 
    } 

    public void setPhone(String phone) { 
     this.phone = phone; 
    } 

    public String getUri() { 
     return uri; 
    } 

    public void setUri(String uri) { 
     this.uri = uri; 
    } 
} 

そして、私はJSON形式で変換するために、リストの行を使用して、次のメソッドを使用します。

@Override 
    public void dataToJsonConverter() { 

     ObjectMapper mapper = new ObjectMapper(); 

     try { 
      String jsonInString = ""; 

      for (HotelData hotels : rows) { 
       jsonInString += mapper.writeValueAsString(hotels); 
      } 

      mapper.writeValue(new File(Constant.OUTPUT_LOC + "/result.json"), jsonInString); 
//   jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(hotelData); 


     } catch (JsonGenerationException e) { 
      e.printStackTrace(); 
     } catch (JsonMappingException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     System.out.println("CONVERTED TO JSON"); 
    } 

ただし、データ量は膨大で、変換に数秒かかる。マルチスレッドを使用してプロセスを高速化する方法は?私はスレッディングに関する多くの経験がないので、質問が適切でない場合は謝罪を受けてください。私はちょうどデータの会話をスピードアップしたい。

更新:驚くべきことに、StringBuilderは、Stringよりも約25倍高速です。 WOW

+0

どのプロセスをスピードアップしますか?ファイルへの書き込み?次に、答えは "no" – UnholySheep

+0

この行は、mapper.writeValue(新しいファイル(Constant.OUTPUT_LOC + "/result.json")、jsonInString); 'JSONファイルにデータを書き込みます。これが不可能な場合、forループのスピードアップはどうですか?私はパフォーマンスを向上させることができれば非常に役に立ちます。 – Chaklader

+0

スレッディングの前に、とにかくファイルへの書き込みを避けることができますか?またはそれを最小化する。 。マルチスレッドに関係なくボトルネックになります。 – Xenwar

答えて

1

マルチスレッド化は不可能ではありませんが、大規模に複雑になります。とにかくメソッドが複雑になる場合は、まずはより速いメソッドを提案します。 (そして、手荷物と並行して解決しなければならない並列ソリューションは対処しなければならない)

ObjectMapperで使用されているリフレクションのため、ストリング化は間違いなく遅いです。あなたがいくつかの余分なプログラミングをしているなら、次の解決方法は速いです。しかし、それは一般的ではありません。

public interface JSONNable { 
    String toJSON(); 
} 


public class HotelData implements JSONNable { 
    private String name; 
    private String address; 
    private String stars; 
    private String contact; 
    private String phone; 
    private String uri; 


    public HotelData(String name, String address, String stars, String contact, String phone, String uri) { 
     this.name = name; 
     this.address = address; 
     this.stars = stars; 
     this.contact = contact; 
     this.phone = phone; 
     this.uri = uri; 
    } 

    public HotelData() { 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getAddress() { 
     return address; 
    } 

    public void setAddress(String address) { 
     this.address = address; 
    } 

    public String getStars() { 
     return stars; 
    } 

    public void setStars(String stars) { 
     this.stars = stars; 
    } 

    public String getContact() { 
     return contact; 
    } 

    public void setContact(String contact) { 
     this.contact = contact; 
    } 

    public String getPhone() { 
     return phone; 
    } 

    public void setPhone(String phone) { 
     this.phone = phone; 
    } 

    public String getUri() { 
     return uri; 
    } 

    public void setUri(String uri) { 
     this.uri = uri; 
    } 

    public String toJSON() { 
     return String.format("{\"name\" : \"%s\", \"address\" : \"%s\", \"stars\" : \"%s\", \"contact\" : \"%s\", \"phone\" : \"%s\", \"uri\" : \"%s\"}", 
      name, address, stars, contact, phone, uri); 
    } 

    /* or any other iterable<HotelData> hotels, including an array */ 
    public static String hotelsToJSON(ArrayList<HotelData> hotels) { 
     StringBuilder sb = new StringBuilder(); 

     sb.append('['); 
     for (HotelData hotelData : hotels) { 
      sb.append(hotel.toJSON()); 
      sb.append(','); 
     } 
     sb.insert(sb.length() - 1, ']'); 
     return sb.toString(); 
    } 
} 

新しいインターフェイスを作成し、toJSON()メソッドを実装する際に、(遅い)HotelDataオブジェクトのランタイム分析があるように持っていないことに留意されたいです。実行時間の違いは、プログラミングに余分な時間を要します。

+0

これは、 'StringBuilder'よりもパフォーマンスが2倍になります。最悪のパフォーマンスは 'String' – Chaklader

0

マルチスレッドでファイルへの書き込み操作を高速化することはできません。スピードアップできる唯一のことは、データのJSON変換です。 ForkJoinPoolまたはExecuterServiceを使用して、複数のスレッド間でデータを分割して処理することで、これを実現できます。最後に、JSON文字列を集めてファイルに書き込むことができます。

ここでは、ForkJoinPoolを使用する方法のチュートリアルを見つけることができ、一般的に動作する方法: ForkJoinPool Tutorial

EDIT

を私はあなたが見ることができる大きさの配列ここで

をソートするための例を持っていますデータといくつかのヘルパメソッドをソートするためにForkJoinPoolによって使用されるRecursiveTask

// class used to store job results 
class SortedArray 
{ 
private int [] array; 

public void setArray(int [] array) 
{ 
    this.array = array; 
} 
public int[] getArray() 
{ 
    return this.array; 
} 
} 


class Sort extends RecursiveTask<SortedArray> 
{ 
     // blocksize that is used to decide whenever insertionsort 
     //  is used or more splits are necessary 
static final int BlockSize = 100; 
private int lb,ub; 
private int [] data; 
public Sort(int lb, int ub, int[] data) 
{ 
    this.lb = lb; 
    this.ub = ub; 
    this.data = data; 
} 

protected SortedArray compute() { 
     // if array size is smaller than the blocksize 
    if((ub - lb) <= BlockSize) 
    { 
     // do insertionSort in the segment 
     insertionSort(this.data, lb, ub); 
    } 
     // if array size is bigger than the blocksize 
    else 
    { 
     if(lb+1 < ub){ 
     // compute mid value for split 
      int mid = (lb+ub)/2; 
     // create new job for the left segment 
      Sort left = new Sort(this.lb,mid,this.data); 
     // create new job for the right segment 
      Sort right = new Sort(mid,this.ub,this.data); 
     // wait for the first job 
      left.fork(); 
     // wait for the second job 
      right.fork(); 
     // redeem data from the first job 
      SortedArray arr1 = left.join(); 
     // redeem data from the second job 
      SortedArray arr2 = right.join(); 
     // merge the data 
      merge(this.data,lb,mid,ub); 
     } 
    } 
     // create SortedArray object to store result 
    SortedArray sArr = new SortedArray(); 
     // set result 
    sArr.setArray(this.data); 
     // return result 
    return sArr; 
    } 
     // given method 
private void insertionSort(int dt[], int a, int b){ 
for(int i = a; i < b; i++){ 
    int j = i; 
    while(j > a && dt[j] < dt[j-1]){ 
      int temp = dt[j]; dt[j] = dt[j-1]; dt[j-1] = temp; 
      j--; 
    } 
} 
} 

private void merge(int f[], int lb, int mid, int ub){ 
    int c[] = new int[ub-lb]; 
    int k = 0;int j = lb; int h = mid; 
    while(j < mid && h < ub){ 
     if(f[j] <= f[h]){ 
      c[k] = f[j]; 
      j++; 
     } 
     else{ 
      c[k] = f[h]; 
      h++; 
     } 
     k++; 
    } 
    while(j < mid){ c[k] = f[j]; k++; j++; } 
    while(h < ub){c[k] = f[h]; k++; h++;} 
    //Now copy data back to array 
    for(int p = 0; p < c.length;p++) 
     f[lb+p] = c[p]; 
} 
} 

および変換ロジックは、時間を取っているし、ファイルへの書き込みがオーバーヘッドでないと思われる場合は、ここで使用例

startTime = System.currentTimeMillis(); 


     // create the array 
int [] arr = new int [10000000]; 
for(int i = 0; i< arr.length;i++) 
{ 
     // fill the array with random values 
    arr[i] = (int)(Math.random()*10000000); 
} 



     // create a ForkJoinPool 
ForkJoinPool fjPool = new ForkJoinPool(); 
     // invoke the sort and store the result in the SortedArray class 
SortedArray sortedArr = fjPool.invoke(new Sort(0, arr.length, arr)); 




endTime = System.currentTimeMillis(); 
runningTime = endTime-startTime; 





System.out.println("============================================"); 
System.out.println("Arraysize: " + arr.length); 
System.out.printf("ForkJoinpool contains %d Threads\n",fjPool.getPoolSize()); 
System.out.println("Running time: "+runningTime + " millisecs (" +(runningTime/1000.0) + ") secs"); 
System.out.println("============================================"); 
System.out.println(); 
+0

ありがとう、この回答でいくつかのサンプルコードがありますか? – Chaklader

+0

サンプルがあれば確かに表示されます –

-1

は、あなたが開始する(例えば)のnスレッドと変換するために、各スレッドにtotalHotel/Nのホテルを割り当てることができます。

ファイルに書き込む方法は2つあります。 A.各スレッドは、それ自身のファイルに書き込みます。 B.すべてのスレッドが1つのファイルに書き込みます。アプローチBは同期を必要とし、変換ロジックが時間のかかる作業ではないことが分かっている場合は、変換が速く、すべてのスレッドが現在のスレッドが終了するのを待っている場合は、アプローチBの実行時間が悪化します。 。

アプローチAを使用する場合は、ファイルをマージし、ファイル1つの出力ファイルに適切な接頭辞と接尾辞を適切に処理するための新しいコードを記述する必要があります。


class Worker implements Runnable { 
    public void run() { 

    } 
} 

これは、あなたが以下のように作成し、run方法でJSONに変換するには、それにいくつかのホテルのオブジェクトを渡すことができ、基本的な労働者実行可能なクラスです。

Thread t = new Thread(new Worker()); 
.... 
t.start(); 

あなたはスレッドtのスタートを呼び出す前にconstuctorまたは任意の他の方法を介した任意の追加データを渡すことができます。

+0

どのように各スレッドに独自のファイルがありますか?それはどのファイル名ですか? – Xenwar

+0

@rkosegiが更新されました – mtk

+0

@Xenwar各スレッドは、tmp .txtというファイルとhttp://docs.oracle.com/javase/7/docs/api/java/lang/Stringというファイルを読み書きする任意の一時ファイルに書き込むことができます。 html#toUpperCase() – mtk

関連する問題