2017-02-11 87 views
0

用java分拣机,即:Java集合排序VS自定义排序 - 速度

Collections.sort(myArrayList, new Comparator<Integer>() { 
     @Override 
     public int compare(Integer o1, Integer o2) { 
     return x; 
     } 

    }); 

myArrayList.sort(new Comparator<Integer>() { 
     @Override 
     public int compare(Integer o1, Integer o2) { 
      return x; 
     } 

    }); 

周围有 '出' 的标签表明,该方法需要600-800毫秒内完成。 100阵列 -

此排序50时,仅仅是太大的延迟。

我的问题是,将创建自定义的方法排序数组是任何更快?

上面的代码工作得很好,但仅仅是方法来实现速度太慢......

每个阵列(myArrayList)有大约44元。

需要600-800毫秒才能完成1次排序,因此50-100个阵列最多可能需要80000毫秒。

可执行文件:

System.out(timeMillis); 
Collections.sort(fourtyFourItemsArrayL, new Comparator<Integer>() { 
      @Override 
      public int compare(Integer o1, Integer o2) { 
       Item i1 = o1 >= 16 ? player.getInventory().getItem(o1 - 16) : player.getEquipment().getItem(o1 - 1); 
       Item i2 = o2 >= 16 ? player.getInventory().getItem(o2 - 16) : player.getEquipment().getItem(o2 - 1); 
       int price1 = i1 == null ? 0 : i1.getDefinitions().getProtectionPrice(); 
       int price2 = i2 == null ? 0 : i2.getDefinitions().getProtectionPrice(); 
       if (price1 > price2) 
        return -1; 
       else if (price1 < price2) 
        return 1; 
       return 0; 
      } 

     }); 
System.out(timeMillis); 
+0

这将取决于。你需要对自己的数组进行排序吗?或者根据它们的元素对数组进行排序(通过元素的某些属性比较数组) – ItamarG3

+0

这些不是“数组”,而是“列表”。你的意思是50-100个列表或列表中的50-100个元素?请提供更完整的示例。 – davidxxx

+2

在潜入这个兔子洞之前,请确保您有数据支持它。在Java中测量性能是非常困难的。看看http://openjdk.java.net/projects/code-tools/jmh/ – Buhb

回答

3

如果我没有记错,Java的Collections.sort()使用排序与复杂度为O(n LG n)的算法。

如果您想要构建比Collections.sort()更快的排序方法,则需要使用O(n)排序算法,如Radix-SortCounting Sort

如果你的约束只有50-100个元素在数组中,我宁愿使用Collections.sort()而不是写很多代码来排序数字。当n < = 100时,O(n lg n)与O(n)之间没有太大差别。

如果要对50-100个不同的阵列进行排序,可以使用Java Threading

0

如果比较的执行速度很慢,那么所有的排序都会或多或少地缓慢。首先,你确实应该确保这种排序所需的一切都可以在内存中使用。 player.getInventory()。getItem(...)做什么?它是否潜入数据库?或一个文件? 如果确实如此,那么您的乘坐感觉很糟糕。 另外,考虑到每个项目都会比compareTo(很多)多一次。 我建议,而不是排序List<Integer>,创建List<Item>然后进行排序的。 这会大大减少您的操作次数Item i1 = o1 >= 16 ? player.getInventory().getItem(o1 - 16) : player.getEquipment().getItem(o1 - 1);

此外,如果i1.getDefinitions().getProtectionPrice()潜入文件,数据库或类似文件,您需要预取。 您可以创建一个仅包含Integer和protectPrice的类,根据原始列表创建此类的列表,然后对其进行排序。我几乎可以保证速度提高100倍左右。总之,我认为你的问题不是排序算法本身,而是你如何实现compareTo,改变排序算法并不能解决你的问题。

+0

getInventory和getEquipment只是地图,因此运行它们不应该花费很多时间,并且getDefinitions,getProectionPrices只是它们各自类中的整数,尽管为了完全清除它们我可以从列表更改fourtyFourItemsArrayL列表会提高性能吗? –

+0

您可以像进行时序测试一样,使用'return o1 - o2'来替换compare(),以便比较比较方法与平凡方法相比贵多少。如果你需要尽可能快的话,我会回答最后的建议,创建一个包含原始整数和价格的类。如果你只需要足够快,那么你可能会稍微修改一下。 – Buhb

+0

这样做显着改善了性能,感谢帮助(实现了地图而不是列表) –