如何减少此循环的执行时间(java)

Jam*_*mes 3 java

我有一段代码,似乎需要花费不寻常的时间来执行.我需要尽可能地降低执行速度.

本质上,代码执行以下操作.我创建了一个对象数组[10] [10] [10].该对象包含一个数字列表,如下所示:

class MyClass{
  ArrayList<Integer> numberList;
      public MyClass(){
          numberList= new ArrayList <Integer> ();
      }
   }


      MyClass storage[][][] = new MyClass[10][10][10];
Run Code Online (Sandbox Code Playgroud)

然后,我有以下代码,将数字添加到列表中

 for(int i =0; i < 200000;i++){
       for(int j = 0; j < 10; j++){
        for(int k = 0; k < 10; k++){
         for(int l = 0; l < 10; l++){            
                   storage[j][k][l].numberList.add(i);
         }
        }
       }
      }
Run Code Online (Sandbox Code Playgroud)

我很确定绝大多数执行时间来自以下行

 storage[j][k][l].numberList.add(i);
Run Code Online (Sandbox Code Playgroud)

更具体地说,它是.add(i).

我是Java的新手,我只熟悉C++.如果ArrayList类似于C++中的列表,那么肯定在末尾添加一个元素需要非常少的CPU时间?是不是因为我做了很多添加操作(可能是一百万)?

我想问的另一件事是我可以通过使用线程加快速度吗?(假设双核处理器有4个线程)我想我可以创建4个线程,每个线程处理50,000个块.但是,我不确定同步.据推测,我必须在存储[] [] []上进行一些互斥.我需要写吗?

synchronized(storage)
Run Code Online (Sandbox Code Playgroud)

或者这样会好吗?

synchronized(storage[j][k][l])
Run Code Online (Sandbox Code Playgroud)

任何帮助非常感谢

问候

Syn*_*r0r 7

永远,永远在记忆数以千万计的数据可能也被存储为原语时,请使用默认的Java包装类.

这是射击自己的最可靠的方法:去过那里,做到了.

new ArrayList <Integer>
Run Code Online (Sandbox Code Playgroud)

可以用Trove的TIntArrayList 简单地替换:

new TIntArrayList
Run Code Online (Sandbox Code Playgroud)

你下载了Trove,它基本上是一个单行更改,在你做你正在做的事情时会节省大量的内存.

为了帮助解决问题:

    final int n = 10000000;

    final List<Integer> l1 = new ArrayList<Integer>( n );
    for (int i = 0; i < n; i++) {
        l1.add( i );
    }

    final TIntArrayList l2 = new TIntArrayList( n );       
    for (int i = 0; i < n; i++) {
        l2.add( i );
    }
Run Code Online (Sandbox Code Playgroud)

第一个循环,使用基于原语的非语义默认Java包装器来保存1000万个整数,在我的机器上执行需要4320毫秒.

第二个需要41毫秒.

这样两个数量级更快.

天真的态度是思考:"两者都是O(1)".

事实是:两者都是O(1),但我正在采用任何一天运行速度快两个数量级的版本.

  • +1 - 虽然"永远,永远"是****太强大**<<. (2认同)