在 for 循环中重新创建 ArrayList 的最快方法

2024-03-22

在Java中,对一个巨大的矩阵X使用以下函数来打印其列不同的元素:

// create the list of distinct values
List<Integer> values = new ArrayList<Integer>();

// X is n * m int[][] matrix
for (int j = 0, x; j < m; j++) {
    values.clear();
    for (int i = 0; i < n; i++) {
        x = X[i][j];
        if (values.contains(x)) continue;
        System.out.println(x);
        values.add(x);
    }
}

首先,我按列(索引 j)进行迭代,并按行(索引 i)进行内部迭代。

对于不同的矩阵,该函数将被调用数百万次,因此应该优化代码以满足性能要求。我想知道值数组。使用起来会更快吗values = new ArrayList<Integer>(); or values = null代替values.clear() ?


更有效的方法是使用Set http://docs.oracle.com/javase/7/docs/api/java/util/Set.html而不是列表,例如HashSet http://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html执行。 contains 方法的运行时间为 O(1),而不是列表的 O(n)。您只需调用 add 方法就可以节省一次调用。

至于你的具体问题,我只是在每个循环中创建一个新的集合 - 对象创建并不那么昂贵,可能比清除集合要少(正如底部的基准测试所证实的那样 - 请参阅编辑2中最有效的版本):

for (int j = 0, x; j < m; j++) {
    Set<Integer> values = new HashSet<Integer>();
    for (int i = 0; i < n; i++) {
        x = X[i][j];
        if (!values.add(x)) continue; //value.add returns true if the element was NOT in the set before
        System.out.println(x);
    }
}

但是,了解哪个更快(新对象与清除对象)的唯一方法是分析代码的该部分并检查两个版本的性能。

EDIT

我运行了一个快速基准测试,清晰的版本似乎比在每个循环中创建一组要快一些(大约快 20%)。您仍然应该检查您的数据集/用例哪一个更好。使用我的数据集编写更快的代码:

Set<Integer> values = new HashSet<Integer>();
for (int j = 0, x; j < m; j++) {
    for (int i = 0; i < n; i++) {
        x = X[i][j];
        if (!values.add(x)) continue; //value.add returns true if the element was NOT in the set before
        System.out.println(x);
    }
    values.clear();
}

EDIT 2

实际上,通过在每个循环中创建一组正确大小的新代码,可以获得更快的代码版本:

for (int j = 0, x; j < m; j++) {
    Set<Integer> values = new HashSet<Integer>(n, 1); //right size from the beginning
    for (int i = 0; i < n; i++) {
        x = X[i][j];
        if (!values.add(x)) continue; //value.add returns true if the element was NOT in the set before
        System.out.println(x);
    }
}

结果总结

JVM 预热 + JIT 后:

Set<Integer> values = new HashSet<Integer>(n, 1); =====> 280 ms
values.clear();                                   =====> 380 ms
Set<Integer> values = new HashSet<Integer>();     =====> 450 ms 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 for 循环中重新创建 ArrayList 的最快方法 的相关文章

随机推荐

  • VSTS 中 .NET Core 项目的代码覆盖率和测试结果

    如何在 VSTS 中启用 NET Core 项目的代码覆盖率和测试结果 目前 尚未为 NET Core 测试任务启用它 这是一个答案的一半 因为我不喜欢代码覆盖率 首先得到dotnet test通过传递参数来输出包含测试结果的 trx 文件
  • 如何在 razor MVC asp.net 中组合两个视图模型

    假设我有一些模型如下 public class Model1 public int ID get set public string Name get set public class Model2 public int ID get se
  • 是否可以将现有的 Windows Phone 8 应用程序更新到 Windows Phone Store 8.1

    我在 Windows Phone 应用商店中有一个 Windows Phone 8 0 应用程序 我想将我的应用程序更新到 Windows Phone 商店 API 而不是 Windows Phone Silverlight 8 1 以准备
  • liferay 7 中 liferay-portlet.xml 的等效文件是什么?

    我想在 liferay 7 中添加自定义用户通知 为此 如果我使用 liferay 6 2 我必须输入类似用户通知定义 and 用户通知处理程序类在 liferay portlet xml 中 但在liferay中我想问一下把这些条目放在哪
  • 如何从 Amazon Kinesis 流获取最新记录?

    我想从 Amazon Kinesis 流中获取最新记录 我打算从该记录中提取时间戳 并将其与消费者应用程序检查点的最后一个记录的时间戳进行比较 以检查消费者是否落后 我无法使用最新的分片迭代器类型 这是因为 LATEST 指向最近的记录之后
  • Richfaces modalPanel 使用 Ajax 加载

    我在我的项目中使用了 richfaces 特别是标签 rich modalPanel 它允许在页面中显示弹出窗口 为此 我添加了这样的弹出窗口
  • 如何将 reCAPTCHA 设为必填字段?

    我正在使用 Google reCAPTCHA 并且能够将 CAPTCHA 组件添加到表单内的页面中 但是当我提交表单时 没有进行验证来检查验证码是否已解决 提交表单时如何验证验证码组件已被解析 或者 换句话说 如何使我的验证码组件成为必需的
  • NestJS,如何以及在哪里构建响应 DTO

    我一直在使用Java Spring框架来开发微服务 最近 我开始探索 NestJS 并有一个关于构建响应 DTO 的问题 在春天 控制器是轻量级的 它们将调用交给服务层 服务层实现业务逻辑 最后 它们调用负责构建响应 DTO 的 Mappe
  • 在 d3.js 中绘制滚动/移动平均值

    寻找一种在 d3 中绘制滚动 移动平均值的方法 而无需提前操作数据 所以我想通过对每个数据点及其后面的两个数据点进行平均来平滑这条线 我的代码是这样的 var data 3 66 2 76 5 20 1 3 8 90 2 5 70 var
  • 当应用程序处于后台/未运行时,不打开通知单击上的特定活动

    仅当打开应用程序并执行通知单击时 通知单击才会启动指定的活动 如果应用程序处于后台 未运行并且执行了通知单击 则应用程序的 MainActivity 将打开 简而言之 就像应用程序按照 Activity 堆栈正常打开一样 而不是打开 Pen
  • 填充无效且无法移除

    来自评论 一旦我手动将填充设置为 无 问题就消失了 这段代码有什么问题吗 VS2010确实可以编译它 但是从VS2010运行时出现错误 说cs close 填充无效 有人可以帮忙吗 谢谢 public static byte Decrypt
  • 如何从javascript中的字符串中删除“,”

    原始字符串是 a d k 我想删除所有 并使其达到 adk 我尝试了下面的代码 但它不起作用 a d k replace 您没有将替换方法的结果分配回您的变量 当您调用replace时 它会返回一个新字符串 而不修改旧字符串 例如 将其加载
  • Wordpress - 选择/加载子菜单项页面时突出显示父菜单项

    我有一个基本菜单 一些菜单项有子菜单 我对 WordPress 的经验很少 现在没有时间深入研究细节 所以我的问题是 当用户导航到子菜单页面之一时突出显示顶部菜单项的最简单方法是什么 我尝试使用 javascript 和纯 css 通过元素
  • 具有动态高度的 CSS 三角形

    想知道是否有人可以帮助解决我遇到的 css 问题 请参阅此 jsbin http jsbin com uviyat 2 edit http jsbin com uviyat 2 edit 注意 较长的措辞示例 如何使三角形箭头指示器垂直缩放
  • 从 XSL 创建 XSL

    我正在尝试从 XSLT 样式表动态生成 XSLT 文档 当然 原则上这是可行的 但我没有让命名空间正常工作 我希望生成的 XSLT 元素带有 xsl 前缀
  • jquery ui滑块,如果满足某些条件则停止滑动

    使用 jQuery UI Slider 我试图找出如何使滑块在满足某些条件后停止工作 有任何想法吗 我认为在 开始 部分停止事件传播会起作用 但是 事实并非如此 所以我还是一无所知 迷失了方向
  • 您可以使用 RedirectToAction 传递模型吗?

    我正在使用 mvc 2 候选版本 并且想知道是否有任何方法可以使用 RedirectToAction 将模型传递给操作 例如 我有一个编辑操作 它采用 ID 从数据库加载记录 在文本框中显示当前值 并让用户编辑并单击提交 public Ac
  • 无法在 Zsh 中使用颜色;文字有效,但没有出现颜色

    我刚买了一台 Mac 我正在尝试用颜色自定义我的 Zsh 提示符 但我无法让颜色起作用 我不确定是因为 LS COLORS 还是什么原因 这是我的 zshrc export CLICOLOR 1 export LSCOLORS ExFxBx
  • C# 没有私有变量的自定义 getter/setter

    我最近学习了c 所以当我学习写属性时 我被教这样做 public string Name get set 汽车属性太棒了 但现在我想做一些更复杂的事情 所以我需要编写一对自定义访问器 private string Name public s
  • 在 for 循环中重新创建 ArrayList 的最快方法

    在Java中 对一个巨大的矩阵X使用以下函数来打印其列不同的元素 create the list of distinct values List