Java 1百万个索引阵列的1x3阵列 - 内存和效率

时间:2015-12-23 17:34:21

标签: java performance memory arraylist

我在空闲时间使用AdventOfCode.com上发布的编码挑战进行一些编码练习

挑战#6涉及使用一组数百条指令打开和关闭100万(虚拟)灯。我发现自己甚至无法填充一个足够大的ArrayList来处理所有这些"灯"

我决定通过制作1000x1000阵列的1x3阵列开始挑战,这些阵列包含" x-coordinate" " y坐标" "开/关"

我对java效率的经验非常有限(除了常识),我非常欣赏一些方向。

如果您有兴趣,可以采取以下挑战:http://adventofcode.com/day/6

这是我的代码到目前为止,遗憾的是我的craptop(4gb内存)上没有超过索引~7000 - 我在家里确实有一个精美的桌面。

对于如何以更好的内存和速度效率来解决这个问题,我将不胜感激。我是一名学习程序员,我会合理地理解任何指导,无论它是什么。 (学习的链接/位置也受到赞赏)

import java.util.ArrayList;

public class Day6 {

    public static void main(String[] args) {
        ReadFileClass myReaderClass = new ReadFileClass();
        ArrayList<String> allLines = myReaderClass.readFile("/C:/Users/Steven/Desktop/Day6.txt");

        ArrayList<ArrayList<Object>> lightArray = new ArrayList<>();

        for(int i = 0; i<=999999; i++){
            if(i%1000 ==0) System.out.println(i); //To see how fast/far the array populates
            int x;
            int y;
            String status = "off";
            for(int j = 0; j<=999; j++){
                x = j;
                y = i%999;
                ArrayList<Object> innerArray = new ArrayList<>();
                innerArray.add(x);
                innerArray.add(y);
                innerArray.add(status);
                lightArray.add(innerArray);
            }
        }

        System.out.println(lightArray); 
    }
}

编辑1 :我不知道ArrayLists究竟发生了什么(垃圾堆积可能?)但我切换到一个字节数组并处理坐标 - &gt;索引转换现在使用方法而且我是一帆风顺。我完成了一个小算法错误后,我会发布我的最终代码(我稍微误解了这个问题)。谢谢你的各种建议!

编辑2 :我的代码现在按预期工作。对于任何有兴趣的人来说,这就是它。)

import java.util.ArrayList;

public class Day6 {

    public static void main(String[] args) {
        ReadFileExample myReaderClass = new ReadFileExample();
        ArrayList<String> allLines = myReaderClass.readFile("/C:/Users/Steven/Desktop/Day6.txt");

        byte[] lightArray = new byte[1000000];

        for(int i = 0; i<=999999; i++){
            lightArray[i] = 0;
        }

        for(String s : allLines){           
            int x1, x2, y1, y2;
            int indexOfFirstNumber = -1;
            String nums = "0123456789";
            for(int i = 0; i<s.length();i++){
                if(nums.indexOf(s.substring(i,i+1))!=-1){
                    indexOfFirstNumber = i;
                    break;
                }
            }
            int IOfirstComma = s.indexOf(",");
            int indexOfThrough = s.indexOf("through");
            int indexOfX2 = indexOfThrough+8;
            int IOsecondComma = s.indexOf(",", IOfirstComma+1);

            x1 = Integer.parseInt(s.substring(indexOfFirstNumber, IOfirstComma));
            y1 = Integer.parseInt(s.substring(IOfirstComma+1, s.indexOf(" ", IOfirstComma)));
            x2 = Integer.parseInt(s.substring(indexOfX2, IOsecondComma));
            y2 = Integer.parseInt(s.substring(IOsecondComma+1,s.length()));

            ArrayList<Integer> indexesToChange = coordinateRangeToIndexArray(x1, y1, x2, y2);

            if(s.substring(0,8).equals("turn off")){
                for(int i : indexesToChange){
                    lightArray[i] = 0;
                }
            }
            else if(s.substring(0,7).equals("turn on")){
                for(int i : indexesToChange){
                    lightArray[i] = 1;
                }
            }
            else if(s.substring(0,6).equals("toggle")){
                for(int i : indexesToChange){
                    if(lightArray[i] == 1){
                        lightArray[i] = 0;
                    }
                    else{
                        lightArray[i] = 1;
                    }
                }
            }
            else{
                System.out.println("Error: Command not recognized");

            }
        }

        //calculate number of lights that are on
        int totalNumLightsOn = 0;
        for(int i = 0; i<lightArray.length;i++){
            if(lightArray[i] == 1){
                totalNumLightsOn++;
            }
        }
        System.out.println(totalNumLightsOn);
    }

    static ArrayList<Integer> coordinateRangeToIndexArray(int x1, int y1, int x2, int y2){
        //Given two coordinates, create an array of all the indexes the smallest possible rectangle encompasses
        final int ROW_SIZE = 1000;
        ArrayList<Integer> affectedIndexes = new ArrayList<>();
        for(int row = x1; row<=x2; row++){
            for(int column = y1; column<=y2; column++){
                affectedIndexes.add(column*ROW_SIZE+row+1);
            }
        }
        return affectedIndexes;
    }
}

3 个答案:

答案 0 :(得分:2)

最有效的内存方式是使用yum install freetype-2.4,在这种情况下,需要1,000,000位(或1兆位)的内存(以及明显的额外几个字节)来存储开/关状态。使用附带的方法可以轻松操作各个位。

祝贺你解决挑战。

答案 1 :(得分:0)

1.000.000每1kb的物体应该需要大约1.000 mb或~1gb。

当我读到你的帖子时,我想

 Map <Integer,Lightswitch> = new HashMap <Integer,Lightswitch>();

也许从一个基本的(空的)Lightswitch开始

 public class Lightswitch {
 }

并将1.000.000的内容添加到地图中。

或(只是想):

byte [] switches = new byte [1000000];

然后字节值代表lightswitch状态(&#39; 0&#39;,&#39; 1&#39;,...)

答案 2 :(得分:0)

只需制作1000X1000的二维整数数组并用0填充它,然后按照说明使用文件处理。例如,将灯光变化0打开为1。