Advertisement
Guest User

Untitled

a guest
Jan 8th, 2021
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 19.85 KB | None | 0 0
  1. //          A performance test of different approaches to look for
  2. //      a minimum in a continually updated array of values. Subjects to test
  3. //      are a naive linear search, TreeSet and PriorityQueue data structures
  4. //      and specially constructed Binary Heap associated with the work array.
  5. //          Work done with idea to use the best approach in the Hungarian algorithm.
  6.  
  7. import java.util.*;
  8.  
  9. public class Test_Performance_Array_Set_Queue {
  10.    
  11.     //private static final long seed = 1610104421273L;
  12.     //private static final long seed = 1610113642540L;
  13.     //private static final long seed = 1610116812045L;
  14.     private static final long seed = System .currentTimeMillis ();
  15.     private static final Random rng = new Random (seed);
  16.    
  17.     private static final int workSize = 150;
  18.     private static final int packSize = 5;
  19.     private static final int maxValue = 30;
  20.     private static final int dataSize = 5000000;
  21.     private static final int [] testData_Indices = new int [dataSize];
  22.     private static final int [] testData_Values  = new int [dataSize];
  23.    
  24.     private static final int iterationsNumber = 17;
  25.     private static final double [] iterationsTimes = new double [iterationsNumber];
  26.     private static final double [] workTimes = new double [8];
  27.    
  28.     private static final boolean debug = false;
  29.     private static final boolean advanced = false;
  30.    
  31.     private static int queueMaxSize;
  32.    
  33.     public static void main (String [] args) {
  34.         int k;
  35.         long startTime, stopTime, result;
  36.         double workTime;
  37.        
  38.         result = 0;
  39.         System .out .println ("Seed: " + seed);
  40.         System .out .println ();
  41.        
  42.         startTime = System .nanoTime ();
  43.         generateTestData ();
  44.         stopTime  = System .nanoTime ();
  45.         System .out .println ("Generation time (ms): " + (1e-6 * (stopTime - startTime)));
  46.         System .out .println ();
  47.        
  48.         for (k = 0; iterationsNumber > k; ++k) {
  49.             startTime = System .nanoTime ();
  50.             result = testArray ();
  51.             stopTime  = System .nanoTime ();
  52.             workTime  = 1e-6 * (stopTime - startTime);
  53.             iterationsTimes [k] = workTime;
  54.             System .out .println ("Array test time (ms): " + workTime);
  55.         }
  56.         System .out .println ("Result: " + result);
  57.         processStats (0);
  58.         System .out .println ();
  59.         //*
  60.         for (k = 0; iterationsNumber > k; ++k) {
  61.             startTime = System .nanoTime ();
  62.             result = testSet ();
  63.             stopTime  = System .nanoTime ();
  64.             workTime  = 1e-6 * (stopTime - startTime);
  65.             iterationsTimes [k] = workTime;
  66.             System .out .println ("Sorted set test time (ms): " + workTime);
  67.         }
  68.         System .out .println ("Result: " + result);
  69.         processStats (2);
  70.         System .out .println ();
  71.        
  72.         for (k = 0; iterationsNumber > k; ++k) {
  73.             startTime = System .nanoTime ();
  74.             result = testQueue ();
  75.             stopTime  = System .nanoTime ();
  76.             workTime  = 1e-6 * (stopTime - startTime);
  77.             iterationsTimes [k] = workTime;
  78.             System .out .println ("Priority queue test time (ms): " + workTime);
  79.         }
  80.         System .out .println ("Result: " + result);
  81.         System .out .println ("Queue maximum size: " + queueMaxSize);
  82.         processStats (4);
  83.         System .out .println ();
  84.         //*/
  85.        
  86.         for (k = 0; iterationsNumber > k; ++k) {
  87.             startTime = System .nanoTime ();
  88.             result = testHeap ();
  89.             stopTime  = System .nanoTime ();
  90.             workTime  = 1e-6 * (stopTime - startTime);
  91.             iterationsTimes [k] = workTime;
  92.             System .out .println ("Binary heap test time (ms): " + workTime);
  93.         }
  94.         System .out .println ("Result: " + result);
  95.         processStats (6);
  96.         System .out .println ();
  97.        
  98.         System .out .print (String .format ("%16d %6d %10d", seed, workSize, dataSize));
  99.         for (k = 0; 8 > k; ++k) {
  100.             if (0 == (k & 1)) {
  101.                 System .out .print (String .format (Locale .UK, " %8.2f", workTimes [k]));
  102.             } else {
  103.                 System .out .print (String .format (Locale .UK, " %5.2f", workTimes [k]));
  104.             }
  105.         }
  106.         System .out .println ();
  107.     }
  108.    
  109.     private static void generateTestData () {
  110.         int k, l, m, index;
  111.         int [] lockedIndices;
  112.         boolean flag;
  113.        
  114.         lockedIndices = new int [packSize];
  115.         Arrays .fill (lockedIndices, -1);
  116.        
  117.         m = 0;
  118.         for (k = 0; dataSize > k; ) {
  119.             index = rng .nextInt (workSize);
  120.             flag = false;
  121.             for (l = 0; packSize > l; ++l) {
  122.                 if (lockedIndices [l] == index) {
  123.                     flag = true;
  124.                     break;
  125.                 }
  126.             }
  127.             if (flag) {
  128.                 continue;
  129.             }
  130.             lockedIndices    [m] = index;
  131.             testData_Indices [k] = index;
  132.             testData_Values  [k] = rng .nextInt (maxValue);
  133.             ++m;
  134.             if (packSize == m) {
  135.                 m = 0;
  136.             }
  137. //            System .out .println (String .format ("%4d%4d%4d", k, index, testData_Values [k]));
  138.             ++k;
  139.         }
  140.     }
  141.    
  142.     @SuppressWarnings("unused")
  143.     private static void processStats (int index) {
  144.         int k, limit;
  145.         double value, sum1, sum2;
  146.        
  147.         if (5 > iterationsNumber) {
  148.             return;
  149.         }
  150.        
  151.         Arrays .sort (iterationsTimes);
  152.         value = 2.0 * iterationsTimes [iterationsNumber / 2];
  153.         value -= iterationsTimes [1];
  154.        
  155.         limit = -1;
  156.        
  157.         for (k = iterationsNumber / 2; iterationsNumber > k; ++k) {
  158.             if (value > iterationsTimes [k]) {
  159.                 limit = k;
  160.             } else {
  161.                 break;
  162.             }
  163.         }
  164.        
  165.         sum1 = 0.0;
  166.         sum2 = 0.0;
  167.        
  168.         for (k = 1; limit > k; ++k) {
  169.             value = iterationsTimes [k];
  170.             sum1 += value;
  171.             sum2 += value * value;
  172.         }
  173.         sum1 /= limit - 1;
  174.         sum2 -= sum1 * sum1 * (limit - 1);
  175.         sum2 = Math .sqrt (sum2 / (limit - 2));
  176.         workTimes [index + 0] = sum1;
  177.         workTimes [index + 1] = sum2;
  178.         System .out .println (sum1 + " " + sum2);
  179.     }
  180.    
  181.     private static long testArray () {
  182.         int k, l, dataIndex, index, value, bestValue, bestIndex;
  183.         long result;
  184.         boolean [] usedFlags;
  185.         int [] auxMinima;
  186.        
  187.         dataIndex = 0;
  188.         result    = 0;
  189.         usedFlags = new boolean [workSize];
  190.         auxMinima = new int     [workSize];
  191.        
  192.         while (dataSize > dataIndex) {
  193.            
  194.             Arrays .fill (usedFlags, false);
  195.             Arrays .fill (auxMinima, Integer .MAX_VALUE);
  196.            
  197.             for (k = 0; workSize > k; ++k) {
  198.                
  199.                 for (l = 0; packSize > l && dataSize > dataIndex; ++l, ++dataIndex) {
  200.                     index = testData_Indices [dataIndex];
  201.                     if (usedFlags [index]) {
  202.                         continue;
  203.                     }
  204.                     value = testData_Values  [dataIndex];
  205.                     if (auxMinima [index] > value) {
  206.                         auxMinima [index] = value;
  207.                     }
  208.                 }
  209.                
  210.                 bestValue = Integer .MAX_VALUE;
  211.                 bestIndex = -1;
  212.                
  213.                 for (l = 0; workSize > l; ++l) {
  214.                     if (usedFlags [l]) {
  215.                         continue;
  216.                     }
  217.                     value = auxMinima [l];
  218.                     if (bestValue > value) {
  219.                         bestValue = value;
  220.                         bestIndex = l;
  221.                     }
  222.                 }
  223.                
  224.                 if (-1 == bestIndex) {
  225.                     break;
  226.                 }
  227.                
  228.                 result += bestValue;
  229.                 usedFlags [bestIndex] = true;
  230.                
  231.                 if (debug) {
  232.                     if (advanced) {
  233.                         displayArray (auxMinima, usedFlags);
  234.                     }
  235.                     System .out .println (dataIndex + "  " + bestIndex + "  " + bestValue + "  " + result);
  236.                 }
  237.             }
  238.         }
  239.        
  240.         return result;
  241.     }
  242.    
  243.     private static long testSet () {
  244.         int k, l, dataIndex, index, value, bestValue, bestIndex;
  245.         long result;
  246.         boolean [] usedFlags;
  247.         int [] auxMinima;
  248.         SortedSet <Integer> sortedMinima;
  249.        
  250.         dataIndex = 0;
  251.         result    = 0;
  252.         usedFlags = new boolean [workSize];
  253.         auxMinima = new int     [workSize];
  254.         sortedMinima = new TreeSet <> (new Comparator <Integer> () {
  255.             @Override
  256.             public int compare (Integer arg1, Integer arg2) {
  257.                 int difference = auxMinima [arg1] - auxMinima [arg2];
  258.                 if (0 != difference) {
  259.                     return difference;
  260.                 }
  261.                 return arg1 - arg2;
  262.             }
  263.         });
  264.        
  265.         while (dataSize > dataIndex) {
  266.            
  267.             Arrays .fill (usedFlags, false);
  268.             Arrays .fill (auxMinima, Integer .MAX_VALUE);
  269.            
  270.             for (k = 0; workSize > k; ++k) {
  271.                
  272.                 for (l = 0; packSize > l && dataSize > dataIndex; ++l, ++dataIndex) {
  273.                     index = testData_Indices [dataIndex];
  274.                     if (usedFlags [index]) {
  275.                         continue;
  276.                     }
  277.                     value = testData_Values  [dataIndex];
  278.                     if (auxMinima [index] > value) {
  279.                         sortedMinima .remove (index);
  280.                         auxMinima [index] = value;
  281.                         sortedMinima .add (index);
  282.                     }
  283.                 }
  284.                
  285.                 if (sortedMinima .isEmpty ()) {
  286.                     break;
  287.                 }
  288.                
  289.                 bestIndex = sortedMinima .first ();
  290.                 bestValue = auxMinima [bestIndex];
  291.                 sortedMinima .remove (bestIndex);
  292. //                if (usedFlags [bestIndex]) {
  293. //                    throw new IllegalArgumentException ("\n\nImpossible algorithm error.\n");
  294. //                }
  295.                 usedFlags [bestIndex] = true;
  296.                 result += bestValue;
  297.                
  298. //                displayArray (auxMinima, usedFlags);
  299. //                System .out .println (dataIndex + "  " + bestValue + "  " + result);
  300.             }
  301.         }
  302.        
  303.         return result;
  304.     }
  305.    
  306.     private static long testQueue () {
  307.         int k, l, dataIndex, index, value, bestValue, bestIndex;
  308.         long result;
  309.         boolean [] usedFlags;
  310.         int [] auxMinima;
  311.         Queue <ValueRecord> sortedMinima;
  312.         ValueRecord valueRecord;
  313.        
  314.         dataIndex = 0;
  315.         result    = 0;
  316.         usedFlags = new boolean [workSize];
  317.         auxMinima = new int     [workSize];
  318.         sortedMinima = new PriorityQueue <> ();
  319.         queueMaxSize = 0;
  320.        
  321.         while (dataSize > dataIndex) {
  322.            
  323.             Arrays .fill (usedFlags, false);
  324.             Arrays .fill (auxMinima, Integer .MAX_VALUE);
  325.            
  326.             for (k = 0; workSize > k; ++k) {
  327.                
  328.                 for (l = 0; packSize > l && dataSize > dataIndex; ++l, ++dataIndex) {
  329.                     index = testData_Indices [dataIndex];
  330.                     if (usedFlags [index]) {
  331.                         continue;
  332.                     }
  333.                     value = testData_Values  [dataIndex];
  334.                     if (auxMinima [index] > value) {
  335.                         auxMinima [index] = value;
  336.                         sortedMinima .add (new ValueRecord (value, index));
  337.                     }
  338.                 }
  339.                
  340.                 if (queueMaxSize < sortedMinima .size ()) {
  341.                     queueMaxSize = sortedMinima .size ();
  342.                 }
  343.                
  344.                 bestValue = Integer .MAX_VALUE;
  345.                 bestIndex = -1;
  346.                
  347.                 while (!sortedMinima .isEmpty ()) {
  348.                     valueRecord = sortedMinima .poll ();
  349.                     if (usedFlags [valueRecord .index]) {
  350.                         continue;
  351.                     }
  352.                     if (auxMinima [valueRecord .index] != valueRecord .value) {
  353.                         continue;
  354.                     }
  355.                     bestValue = valueRecord .value;
  356.                     bestIndex = valueRecord .index;
  357.                     break;
  358.                 }
  359.                
  360.                 if (-1 == bestIndex) {
  361.                     break;
  362.                 }
  363.                
  364.                 usedFlags [bestIndex] = true;
  365.                 result += bestValue;
  366.                
  367. //                displayArray (auxMinima, usedFlags);
  368. //                System .out .println (dataIndex + "  " + bestValue + "  " + result);
  369.             }
  370.         }
  371.        
  372.         return result;
  373.     }
  374.    
  375.     @SuppressWarnings("unused")
  376.     private static long testHeap () {
  377.         int k, l, dataIndex, heapSize, valueIndex, value, auxIndex, nextAuxIndex, heapIndex;
  378.         int bestValue, bestIndex, nextValue, childAuxIndex, childHeapIndex, childValue;
  379.         long result;
  380.         boolean flag;
  381.         boolean [] usedFlags;
  382.         int [] auxMinima, auxIndices, binaryHeap;
  383.        
  384.         dataIndex  = 0;
  385.         result     = 0;
  386.         usedFlags  = new boolean [workSize];
  387.         auxMinima  = new int     [workSize];
  388.         auxIndices = new int     [workSize];
  389.         binaryHeap = new int     [workSize];
  390.         auxIndex   = 0;
  391.        
  392.         while (dataSize > dataIndex) {
  393.            
  394.             Arrays .fill (usedFlags, false);
  395.             Arrays .fill (auxMinima, Integer .MAX_VALUE);
  396.             Arrays .fill (auxIndices, -1);
  397.             heapSize = 0;
  398.            
  399.             for (k = 0; workSize > k; ++k) {
  400.                
  401.                 for (l = 0; packSize > l && dataSize > dataIndex; ++l, ++dataIndex) {
  402.                     valueIndex = testData_Indices [dataIndex];
  403.                     if (usedFlags [valueIndex]) {
  404.                         continue;
  405.                     }
  406.                     value = testData_Values  [dataIndex];
  407.                     flag = true;
  408.                     if (-1 == auxIndices [valueIndex]) {
  409.                         auxIndex = heapSize;
  410.                         ++heapSize;
  411.                         flag = false;
  412.                     } else if (auxMinima [valueIndex] > value) {
  413.                         auxIndex = auxIndices [valueIndex];
  414.                         flag = false;
  415.                     }
  416.                     if (flag) {
  417.                         continue;
  418.                     }
  419.                     auxMinima [valueIndex] = value;
  420.                     while (0 < auxIndex) {
  421.                         nextAuxIndex = (auxIndex - 1) / 2;
  422.                         heapIndex = binaryHeap [nextAuxIndex];
  423.                         nextValue = auxMinima [heapIndex];
  424.                         if (value > nextValue || value == nextValue && valueIndex >= heapIndex) {
  425.                             break;
  426.                         }
  427.                         binaryHeap [auxIndex] = heapIndex;
  428.                         auxIndices [heapIndex] = auxIndex;
  429.                         auxIndex = nextAuxIndex;
  430.                     }
  431.                     binaryHeap [auxIndex] = valueIndex;
  432.                     auxIndices [valueIndex] = auxIndex;
  433.                 }
  434.                
  435.                 if (debug && advanced) {
  436.                     displayArray (auxIndices);
  437.                 }
  438.                
  439.                 if (0 == heapSize) {
  440.                     break;
  441.                 }
  442.                
  443.                 bestIndex = binaryHeap [0];
  444.                 bestValue = auxMinima [bestIndex];
  445.                 auxIndices [bestIndex] = -1;
  446.                 --heapSize;
  447.                 valueIndex = binaryHeap [heapSize];
  448.                 value = auxMinima [valueIndex];
  449.                 auxIndex = 0;
  450.                 //binaryHeap [0] = valueIndex;
  451.                
  452.                 while (true) {
  453.                     nextValue = value;
  454.                     heapIndex = valueIndex;
  455.                     nextAuxIndex = auxIndex;
  456.                     childAuxIndex = 2 * auxIndex + 1;
  457.                     if (heapSize > childAuxIndex) {
  458.                         childHeapIndex = binaryHeap [childAuxIndex];
  459.                         childValue = auxMinima [childHeapIndex];
  460.                         if (nextValue > childValue || nextValue == childValue && heapIndex > childHeapIndex) {
  461.                             nextValue = childValue;
  462.                             heapIndex = childHeapIndex;
  463.                             nextAuxIndex = childAuxIndex;
  464.                         }
  465.                     }
  466.                     ++childAuxIndex;
  467.                     if (heapSize > childAuxIndex) {
  468.                         childHeapIndex = binaryHeap [childAuxIndex];
  469.                         childValue = auxMinima [childHeapIndex];
  470.                         if (nextValue > childValue || nextValue == childValue && heapIndex > childHeapIndex) {
  471.                             heapIndex = childHeapIndex;
  472.                             nextAuxIndex = childAuxIndex;
  473.                         }
  474.                     }
  475.                     if (auxIndex == nextAuxIndex) {
  476.                         break;
  477.                     }
  478.                     binaryHeap [auxIndex] = heapIndex;
  479.                     auxIndices [heapIndex] = auxIndex;
  480.                     auxIndex = nextAuxIndex;
  481.                 }
  482.                 binaryHeap [auxIndex] = valueIndex;
  483.                 auxIndices [valueIndex] = auxIndex;
  484.                
  485.                 result += bestValue;
  486.                 usedFlags [bestIndex] = true;
  487.                
  488.                 if (debug) {
  489.                     if (advanced) {
  490.                         displayArray (auxMinima, usedFlags);
  491.                         displayArray (auxIndices);
  492.                     }
  493.                     System .out .println (dataIndex + "  " + bestIndex + "  " + bestValue + "  " + result);
  494.                 }
  495.             }
  496.         }
  497.        
  498.         return result;
  499.     }
  500.    
  501.     private static void displayArray (int [] array, boolean [] flags) {
  502.         int k, value;
  503.        
  504.         for (k = 0; workSize > k; ++k) {
  505.             value = array [k];
  506.             if (Integer .MAX_VALUE == value) {
  507.                 if (flags [k]) {
  508.                     System .out .print (" ####");
  509.                 } else {
  510.                     System .out .print ("   - ");
  511.                 }
  512.             } else {
  513.                 if (flags [k]) {
  514.                     System .out .print (String .format ("%4s<", ">" + value));
  515.                 } else {
  516.                     System .out .print (String .format ("%4d ", value));
  517.                 }
  518.             }
  519.         }
  520.         System .out .println ();
  521.     }
  522.    
  523.     private static void displayArray (int [] array) {
  524.         int k, value;
  525.        
  526.         for (k = 0; workSize > k; ++k) {
  527.             value = array [k];
  528.             if (-1 == value) {
  529.                 System .out .print ("   - ");
  530.             } else {
  531.                 System .out .print (String .format ("%4d ", value));
  532.             }
  533.         }
  534.         System .out .println ();
  535.     }
  536.    
  537.     private static class ValueRecord implements Comparable <ValueRecord> {
  538.        
  539.         private int value, index;
  540.        
  541.         public ValueRecord (int argValue, int argIndex) {
  542.             value = argValue;
  543.             index = argIndex;
  544.         }
  545.  
  546.         @Override
  547.         public int compareTo (ValueRecord arg) {
  548.             int difference = value - arg .value;
  549.             if (0 != difference) {
  550.                 return difference;
  551.             }
  552.             return index - arg .index;
  553.         }
  554.     }
  555. }
  556.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement