做网站费用可以看为广告费用吗,深圳大腕互联网站建设,分享音乐到wordpress,网站购买流程在使用Java编程语言时#xff0c;我们将继续讨论与建议的实践有关的系列文章#xff0c;我们将在三个最常用的Collection实现类之间进行性能比较。 为了使事情变得更现实#xff0c;我们将在多线程环境下进行测试#xff0c;以讨论和演示如何将Vector #xff0c; ArrayLi… 在使用Java编程语言时我们将继续讨论与建议的实践有关的系列文章我们将在三个最常用的Collection实现类之间进行性能比较。 为了使事情变得更现实我们将在多线程环境下进行测试以讨论和演示如何将Vector ArrayList和/或HashSet用于高性能应用程序。 所有讨论的主题均基于用例这些用例来自于电信行业的关键任务超高性能生产系统的开发。 在阅读本文的每个部分之前强烈建议您参考相关的Java API文档以获取详细信息和代码示例。 所有测试均针对具有以下特征的Sony Vaio进行 系统openSUSE 11.1x86_64 处理器CPUIntelRCoreTM2 Duo CPU T6670 2.20GHz 处理器速度1,200.00 MHz 总内存RAM2.8 GB JavaOpenJDK 1.6.0_0 64位 应用以下测试配置 并发工作线程数50 每个工作人员测试重复次数100 整体测试次数100 向量vs ArrayList vs HashSet Java开发人员必须执行的最常见任务之一是从Collections中存储和检索对象。 Java编程语言提供了一些具有重叠和独特特征的Collection实现类。 Vector ArrayList和HashSet可能是最常用的。 但是使用Collection实现类 特别是在多线程环境中可能会很棘手。 默认情况下它们中的大多数不提供同步访问。 因此以并行方式更改Collection的内部结构插入或缩回元素肯定会导致错误。 这里将要讨论的案例场景是通过上述每个Collection实现类的元素进行多个Thread的插入缩回和迭代。 我们将演示如何在多线程环境中正确利用上述集合实现类并提供相关的性能比较表以显示在每个测试用例中哪个性能更好。 为了进行票价比较我们将假定不允许使用NULL元素并且我们不介意Collections中元素的顺序。 此外由于矢量是唯一集合实现类我们的测试组提供了默认的同步访问同步的ArrayList和HashSet的 集合实现类将使用Collections.synchronizedList和Collections.synchronizedSet静态方法来实现。 这些方法提供了指定Collection实现类的“包装”同步实例如下所示 列表syncList Collections.synchronizedListnew ArrayList; 设置syncSet Collections.synchronizedSetnew HashSet; 测试用例1 –在集合中添加元素 对于第一个测试用例我们将有多个线程在每个Collection实现类中添加String元素。 为了保持String元素之间的唯一性我们将如下所示构造它们 静态的第一部分例如“ helloWorld” 工作线程ID请记住我们有50个并发运行的工作线程 worker线程测试重复次数请记住每个worker线程每次测试执行100次测试重复 对于每个测试运行每个工作线程将插入100个String元素如下所示 对于第一次测试重复 工作线程1将插入String元素“ helloWorld-1-1” 对于第二次测试重复 工作线程1将插入String元素“ helloWorld-1-2” 等等... 在每次测试运行结束时每个Collection实现类都将填充5000个不同的String元素。 下面我们展示了上述三个Collection实现类之间的性能比较表 横轴表示测试运行的次数纵轴表示每次测试运行的每秒平均事务数TPS。 因此较高的值更好。 如您所见在向Vector和ArrayList Collection实现类添加元素时它们的执行效果几乎相同。 另一方面 HashSet Collection实现类的性能稍差主要是由于内部结构和哈希生成机制更加复杂。 测试案例2 –从集合中删除元素 对于第二个测试用例我们将有多个线程从每个Collection实现类中删除String元素。 所有集合实现类都将使用来自先前测试用例的String元素进行预填充。 为了删除元素我们将为每个Collection实现类在所有工作线程之间利用共享的Iterator实例。 对Iterator实例的同步访问也将实现。 每个工作线程都将删除Collection实现类的下一个可用元素并发出“ next”和“ remove” 迭代器操作以避免ConcurrentModificationException 。 下面是上述测试用例的性能比较表。 横轴表示测试运行的次数纵轴表示每次测试运行的每秒平均事务数TPS。 因此较高的值更好。 同样从中移除String元素时 Vector和ArrayList Collection实现类的性能几乎相同。 另一方面 HashSet Collection实现类的性能远远优于Vector和ArrayList 平均速度为678000 TPS。 在这一点上我们必须指出通过使用Vector和ArrayList Collection实现类的“ remove0”方法删除String元素与使用同步共享Iterator实例相比我们获得了更好的性能结果。 我们之所以演示同步共享Iterator实例“ next”和“ remove”操作方法是为了维持三个Collection实现类之间的票价比较。 重要的提醒 我们的测试用例场景要求我们从每个Collection实现类中删除第一个元素。 尽管如此我们必须指出这对于Vector和ArrayList Collection实现类是最坏的情况。 作为我们的读者之一詹姆斯·沃森James Watson成功评论了TheServerSide的相关帖子 “ 原因是在ArrayList和Vecrtor上如果删除了除最后一个元素以外的任何元素最后一个元素是索引为size – 1的元素则remove方法将导致System.arraycopy调用。 删除第一个元素意味着将复制数组的整个其余部分这是一个On操作。 由于测试删除了列表中的所有元素因此完整测试变为On ^ 2缓慢。 HashSet remove不执行任何此类数组副本因此它的删除时间为O1或恒定时间。 对于完整测试则为On快速。 如果重写测试以从ArrayList和Vector中删除最后一个元素则性能可能与HashSet相似。 ” 因此我们将再次进行此测试从Vector和ArrayList Collection实现类中删除最后一个元素因为我们假定Collections中元素的顺序并不重要。 性能结果如下所示。 横轴表示测试运行的次数纵轴表示每次测试运行的每秒平均事务数TPS。 因此较高的值更好。 不出所料从其中删除String元素时所有Collection实现类的性能几乎相同。 测试案例3 –迭代器 对于第三个测试用例我们将有多个工作线程在每个Collection实现类的元素上进行迭代。 每个工作线程将使用Collection “ iterator”操作检索对Iterator实例的引用并使用Iterator “ next”操作遍历所有可用的Collection元素。 所有Collection实现类都将使用第一个测试用例的String值预先填充。 下面是上述测试用例的性能比较表。 横轴表示测试运行的次数纵轴表示每次测试运行的每秒平均事务数TPS。 因此较高的值更好。 与ArrayList Collection实现类相比 Vector和HashSet Collection实现类的性能均较差。 Vector平均获得68 TPS而HashSet平均获得9200 TPS。 另一方面到目前为止 ArrayList的性能优于Vector和HashSet 平均速度为421000 TPS。 测试案例4 –添加和删除元素 对于我们的最终测试用例我们将实现测试用例1和测试用例2场景的组合。 一组辅助线程将向每个Collection实现类插入String元素而另一组辅助线程将从其中撤回String元素。 在组合添加和缩回元素操作中无法使用用于删除元素的同步共享Iterator实例方法。 由于Collection的内部结构在不断变化因此从单个Collection中同时添加和删除元素可避免使用共享的Iterator实例。 对于Vector和ArrayList Collection实现类可以通过使用“ remove0”操作来绕过上述限制该操作将从Collection内部存储器中收回第一个元素。 不幸的是 HashSet Collection实现类不提供此类功能。 我们建议的使用HashSet Collection实现类为组合操作获得最大性能的方法如下 使用两个不同的HashSet一个用于添加元素另一个用于撤回 实现一个“控制器” 线程 该线程将在“收回” HashSet为空时交换上述HashSet类的内容。 “控制器” 线程可以实现为常规TimerTask 可以定期检查“缩回” HashSet的内容并在需要时执行交换 交换两个HashSet时应为“收回” HashSet创建一个共享的Iterator实例。 所有撤消元素的辅助线程应等待“撤消” HashSet充满元素并在交换后得到通知 以下是显示建议实施的代码段 全球宣言 Setstring s new HashSetstring(); // The HashSet for retracting elements
Iteratorstring sIt s.iterator(); // The shared Iterator for retracting elements
Setstring sAdd new HashSetstring(); // The HashSet for adding new elements
Boolean read Boolean.FALSE; // Helper Object for external synchronization and wait – notify functionality when retracting elements from the “s” HashSet
Boolean write Boolean.FALSE; // Helper Object for external synchronization when writing elements to the “sAdd” HashSet 用于将元素添加到“ sAdd” HashSet的代码 synchronized(write) {sAdd.add(“helloWorld” - threadId - count);
} 用于从“ s” HashSet中撤回元素的代码 while (true) {synchronized (read) {try {sIt.next();sIt.remove();break;} catch (NoSuchElementException e) {read.wait();}}
} “控制器”类代码 public class Controller extends TimerTask {public void run() {try {performSwap();} catch (Exception ex) {ex.printStackTrace();}}private void performSwap() throws Exception {synchronized(read) {if(s.isEmpty()) {synchronized(write) {if(!sAdd.isEmpty()) {Setstring tmpSet;tmpSet s;s sAdd;sAdd tmpSet;sIt s.iterator();read.notifyAll();}}}}}} 最后安排“控制器” TimerTask的代码 Timer timer new Timer();
timer.scheduleAtFixedRate(new Controller(), 0, 1); 我们应该先启动“控制器”任务然后再启动对相关HashSet进行读写的辅助线程 。 请记住对于Vector和ArrayList Collection实现类我们使用了“ remove0”操作来收回元素。 以下是上述Collection实现类的代码段 while (true) {try {vector.remove(0);break;} catch (ArrayIndexOutOfBoundsException e) {}
}while (true) {try {syncList.remove(0);break;} catch (IndexOutOfBoundsException e) {}
} 下面是上述测试用例的添加部分的性能比较表。 以下是上述测试案例的收回部分的性能比较表。 横轴表示测试运行的次数纵轴表示每次测试运行的每秒平均事务数TPS。 因此较高的值更好。 Vector和ArrayList Collection实现类在添加和撤消元素时的性能几乎相同。 另一方面对于元素添加测试用例与Vector和ArrayList实现相比我们建议的实现带有“添加”和“缩回” HashSet对的性能略逊一筹。 但是对于元素撤回测试用例我们的“添加”和“撤回” HashSet对实现比Vector和ArrayList实现都要好平均得分为6000 TPS。 快乐编码 贾斯汀 相关文章 Java最佳实践–多线程环境中的DateFormat Java最佳实践–高性能序列化 Java最佳实践–字符串性能和精确字符串匹配 Java最佳实践–队列之战和链接的ConcurrentHashMap Java最佳实践– Char到Byte和Byte到Char的转换 相关片段 ArrayList大小示例 将Collection的所有元素插入特定的ArrayList索引 在HashSet示例中检查元素是否存在 HashSet迭代器示例 Java Map示例 将元素添加到Vector示例的指定索引 翻译自: https://www.javacodegeeks.com/2010/08/java-best-practices-vector-arraylist.html