2014-05-09 2 views
0

약 50000 개의 행을 가진 파일을 구문 분석해야하며 각 행을 반복하고 구문 분석하고 목록을 만들고 데이터베이스에 저장해야합니다. 처음에는 파일을 읽는 시간이 걸렸다고 생각했습니다. 그러나 실제로 파일은 1 초 안에 읽혀집니다. 그러나 데이터 구문 분석에는 오랜 시간이 걸립니다.Java - 큰 문자열 목록을 통한 반복 개선

public static final String record  = "dlrCode,partNumber,5,0.00,5000.00,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0,0.00,0"; 
    public static final String COMMA  = ","; 
    public static final String QUOTES  = "\""; 
    public static final String EMPTY_STRING = ""; 

    public static void main(String[] args){ 


     List<String> recordsList   = new ArrayList<String>(); 
     Date time       = new Date(); 
     Part partVO       = null; 
     PartHistory partHistoryVO   = null; 
     List<PartHistory> partHistoryList = null; 
     List<Part> partsList    = new ArrayList<Part>(); 
     int splitLength      = 0; 
     Calendar cal      = Calendar.getInstance(); 
     int historySplitCount    = 0; 
     int monthCountReverse    = 0; 

     //add 20000 records to list 
     for(int i=0; i<20000; i++){ 
      recordsList.add(record); 
     } 
     System.out.println("Added in "+((new Date()).getTime() - time.getTime()) +" ms"); 

     //reset time 
     time       = new Date(); 

     //parse records 
     for(String sCurrentLine : recordsList){ 
      partVO = new Part(); 
      partHistoryList = new ArrayList<PartHistory>(); 

      //Parsing inventory information 
      partVO.setDealerCode(sCurrentLine.split(COMMA)[0]); 
      partVO.setPartNumber(sCurrentLine.split(COMMA)[1]); 
      partVO.setDmsMfId(sCurrentLine.split(COMMA)[2]); 
      partVO.setQtyOnHand(Math.round(Float.parseFloat(sCurrentLine.split(COMMA)[3]))); 
      partVO.setDealerNet(Float.parseFloat(sCurrentLine.split(COMMA)[4])); 

      //Parsing history information 
      //starting from the 6th record as the first 5 records are used above 
      historySplitCount = 5; 

      //to subtract one month from current date 
      monthCountReverse = -1; 

      splitLength = sCurrentLine.split(COMMA).length; 

      while(splitLength>=(historySplitCount+1)){ 

       partHistoryVO = new PartHistory(); 
       //subtract one month from current date 
       cal.add(Calendar.MONTH, monthCountReverse); 
       partHistoryVO.setMonth(cal.get(Calendar.MONTH)+1); 
       partHistoryVO.setYear(cal.get(Calendar.YEAR)); 

       partHistoryVO.setLineHitsMonthly(Math.round(Float.parseFloat(sCurrentLine.split(COMMA)[historySplitCount]))); 
       historySplitCount++; 

       partHistoryVO.setQuantity(Math.round(Float.parseFloat(sCurrentLine.split(COMMA)[historySplitCount]))); 
       historySplitCount++; 
       partHistoryList.add(partHistoryVO); 
      } 
      partVO.setHistoryList(partHistoryList); 

      partsList.add(partVO); 
     } 
     System.out.println("Iterated in "+((new Date()).getTime() - time.getTime()) +" ms"); 
    } 

출력

Added in 15 ms 
Iterated in 12823 ms 

는 반복 시간은 개선이어야 오초에서 기세 할 수 있습니까?

+1

당신은 자바 8 –

+0

목에 병렬 스트림을 사용하여 그것을 할 수를 만들 필요가 없습니다 anks! 불행하게도 애플리케이션은 Java 6를 사용하며 변경할 수 없습니다. Java 6에 대한 제안 사항은 무엇입니까? –

+1

매번 줄을 나누는 이유는 무엇입니까? 쉼표로 줄을 나눌 수 없습니까? 그 배열을 단일 배열에 넣은 다음 해당 배열을 해당 while의 범위로 사용합니까? – CodeChimp

답변

3

코드에서 sCurrentLine.split(COMMA)번을 여러 번 부릅니다. 루프에서 처음으로 호출 할 때 final String[] 변수를 변수로 사용하고 그 후에 대신 그 변수를 사용하면 여러 번 더 빠르게 처리 할 수 ​​있습니다.

+0

좋아요! 2 초가되었습니다! 감사! –

1

각 라인의 경우, 스플릿() 함수를 여러 번 sCurrentLine.split (COMMA) [0]

나은 방법 배열

String[] elements = sCurrentLine.split(COMMA); 
dealerCode = elements[0]; 
partNumber = elements[1]; 
로 한번 분리하고 저장하는 전화 소비 한 시간을, 당신은 또한 System.currentTimeMillis()을 사용할 수 있습니다

가 참고로, 계산이 새로운 날짜 인스턴스 :

long timeStarts = System.currentTimeMillis(); 
//loop goes here 
long timeTook = System.currentTimeMillis() - timeStarts; 
관련 문제