Java - 通过大型字符串列表改进迭代

时间:2014-05-09 21:05:20

标签: java performance iteration

我必须解析有大约50000行的文件,并且必须遍历每一行,解析,创建一个List并保存到数据库。最初我认为所花费的时间是因为阅读文件。但该文件实际上是在一秒钟内读取的。但解析数据需要很长时间。

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

迭代时间是否可以改善并且至少需要5秒钟?

2 个答案:

答案 0 :(得分:3)

你正在打电话 sCurrentLine.split(COMMA) 在您的代码中多次。做一个 final String[] 变量第一次在循环中调用它并在之后使用它,它会更快地得到它。

答案 1 :(得分:1)

对于每一行,你多次调用split()函数,sCurrentLine.split(COMMA)[0],

更好的方法是将其拆分一次并存储到数组中

String[] elements = sCurrentLine.split(COMMA);
dealerCode = elements[0];
partNumber = elements[1];

仅供参考,要计算花费的时间,您还可以使用System.currentTimeMillis(),这不需要创建新的Date实例:)

long timeStarts = System.currentTimeMillis();
//loop goes here
long timeTook = System.currentTimeMillis() - timeStarts;