两个for循环,内部for循环增加1000倍,而速度只增加100倍?

时间:2012-05-05 11:16:37

标签: java algorithm complexity-theory

我正在分析算法的计算复杂度,我有两个for循环。

    short i=0;
    short j=0;
    short ii=0;
    short[] counts = new short[2];

    int label_size  = MapRedUtils.label_size;
    int max_index=0;                        
    int sample_size =data.getSampleSize();

    float max_ig = 0;
    float totalVar=0;
    float var=0;
    float cov_ig;

    float[] tocopy = new float[label_size];        
    float[][] sums = new float[2][];
    float[] totalSum = new float[label_size];



    byte value;
    ByteBuffer label = ByteBuffer.allocate(label_size*4); 

    for( j=0; j<2; j++ )        
        sums[j] = new float[label_size];

    for( ii=0; ii<3; ii++)// 3 ways of split the current node
    {          
          long startTime;
    long endTime;
    long totalTime;
    startTime = System.currentTimeMillis();
        counts[0]=0;
        counts[1]=0;

        System.arraycopy(tocopy,0,totalSum,0,label_size);
        System.arraycopy(tocopy,0,sums[0],0,label_size);
        System.arraycopy(tocopy,0,sums[1],0,label_size);

        for ( i = 0; i < sample_size; i++) 
        {
            OneSample instance = data.get(i);
            value = (byte) instance.getTheGenoytpe(snpid);

            label = instance.getPhenotype();                                                                          

            if( value==ii)
            {   
                counts[0]++;
                for(j=0; j< label_size; j++)
                     sums[0][j] += label.getFloat(j*4);
            }
            else
            {
                counts[1]++;                    
                for(j=0; j< label_size; j++)
                    sums[1][j] += label.getFloat(j*4);                    
            }

            for(j=0; j< label_size; j++)  
                totalSum[j] += label.getFloat(j*4);
        }                                              

          totalVar=0;
          var=0;
         for(i=0; i< label_size; i++)
         {
           totalVar += totalSum[i]*totalSum[i];          
         } 

        totalVar = totalVar/sample_size;//it is averaged by sample size

        for(j=0; j< 2; j++)
           //var += sumSquared(sums[j],  MapRedUtils.inverse_covariance , counts[j]);  
             var += sumSquared(sums[j], counts[j]);


        cov_ig = var- totalVar;

        if(cov_ig > max_ig)
        {
            max_ig=cov_ig;
            max_index=ii;
        } 
        endTime = System.currentTimeMillis();                    
        totalTime = (endTime - startTime);
        System.out.println(totalTime);

我从label_size = 1和label_size = 1000增加内部label_size,我希望运行时间增加1000倍,而实际运行时间增加不到40-100次。  为什么会这样?

1 个答案:

答案 0 :(得分:1)

当label = 1时,外循环的大部分时间都在“在这里做一些事情”并设置内循环,因为在循环中只运行一次“在这里也做一些事情”只是一小部分工作。假设“在这里做点什么”并且设置内循环需要100个单位的时间并且“在这里做一些事情”只需要10个单位的时间。程序的总运行时间为110 * sample_size。现在您将标签增加到1000. 100 + 10 * 1000 = 10100.因此总运行时间为10100 * sample_size。 10100/110 = 91.8。因为“在这里做点什么”花了一些时间,它大大减少了增加标签的影响。你必须考虑“在这里做点什么”和“在这里做点什么”的比例,而不仅仅是旧标签价值与新标签价值的比率。