简体   繁体   English

为什么使用布尔数组需要这么长时间?

[英]Why does using a boolean array take so much longer?

I am working on an assignment for class. 我正在上课作业。 I am supposed to create a simple version of Conway's Game of Life. 我应该创建一个Conway的《人生游戏》的简单版本。 I was doing some experimenting between using an array of boolean values vs using a BitSet. 我在使用布尔值数组与使用BitSet之间进行了一些实验。 I ended up creating this little test: 我最终创建了这个小测试:

After running the test each time for both the BitSet, and the boolean array, bitset had an average of about 6ms, and the boolean array had an average of about 1300ms. 每次对BitSet和布尔数组都运行测试后,bitset的平均值约为6ms,布尔数组的平均值约为1300ms。 So my question is, what exactly is causing the HUGE overhead in times with using booleans over using a BitSet? 所以我的问题是,究竟是什么导致使用布尔值而不是使用BitSet导致时间的巨大开销? I expected a difference, but not something this drastic. 我期望有所不同,但不会如此剧烈。

Here is the code: 这是代码:

Life.java - main class Life.java-主类

public class Life
{
    private final int WIDTH = 100;
    private final int HEIGHT = 100;
    private Board board;

    public static void main(String[] args)
    {
        new Life();
    }

    public Life()
    {
        board = createBoard();

        // populate board with random data
        Random random = new Random();
        for (int j = 0; j < board.length(); j++)
        {
            boolean b = random.nextBoolean();
            board.set(j, b);
        }
        random = null;
        System.gc();


        System.out.println("Starting test...");
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 10_000; i++)
        {
            Board tempBoard = createBoard();
            for (int j = 0; j < board.length(); j++)
            {
                byte count = getNeighborCount(j);
                boolean value = board.get(j);
                boolean next = value ? count >= 2 && count <= 3 : count == 3;
                tempBoard.set(j, next);
            }
            board = tempBoard;
        }

        long endTime = System.currentTimeMillis();
        System.out.format("Took %d ms", endTime - startTime);
    }

    public Board createBoard()
    {
        return new ArrayBoard(WIDTH * HEIGHT);
        //return new BitBoard(WIDTH * HEIGHT);
    }

    public byte getNeighborCount(int index)
    {
        byte count = 0;

        if (getRelative(index, -1, -1)) count++;
        if (getRelative(index, -1, 0)) count++;
        if (getRelative(index, -1, 1)) count++;

        if (getRelative(index, 0, -1)) count++;
        if (getRelative(index, 0, 0)) count++;
        if (getRelative(index, 0, 1)) count++;

        if (getRelative(index, 1, -1)) count++;
        if (getRelative(index, 1, 0)) count++;
        if (getRelative(index, 1, 1)) count++;

        return count;
    }

    public boolean getRelative(int index, int x, int y)
    {
        int relativeIndex = index + (WIDTH * y) + x;
        return board.get(relativeIndex);
    }
}

Board implementation using BitSet 使用BitSet的电路板实施

public class BitBoard implements Board
{
    private BitSet board;

    public BitBoard(int size)
    {
        board = new BitSet(size);
    }

    @Override
    public void set(int index, boolean value)
    {
        if (value) board.set(index);
        else board.clear(index);
    }

    @Override
    public boolean get(int index)
    {
        return board.get(index);
    }

    @Override
    public int length()
    {
        return board.length();
    }
}

Board implementation using an Array 使用阵列的电路板实施

public class ArrayBoard implements Board
{
    private boolean[] board;

    public ArrayBoard(int size)
    {
        board = new boolean[size];
    }

    @Override
    public void set(int index, boolean value)
    {
        board[index] = value;
    }

    @Override
    public boolean get(int index)
    {
        boolean output = false;
        if (index >= 0 && index < board.length)
            output = board[index];
        return output;
    }

    @Override
    public int length()
    {
        return board.length;
    }
}

And finally, Board.java 最后,Board.java

public interface Board
{
    public boolean get(int index);

    public void set(int index, boolean value);

    public int length();
}

Your problem has nothing to do with BitSet vs. boolean[] performance. 您的问题与BitSetboolean[]性能无关。

In your BitSetBoard , you have length() defined as: BitSetBoard ,您将length()定义为:

class BitSetBoard {

    ...

    @Override
    public int length()
    {
        return board.length();
    }

}

You mean to return board.size() not board.length() . 您的意思是返回board.size()而不是board.length() The BitSet.length() method returns the index of the highest bit set, it does not return the total size. BitSet.length()方法返回的最高位集合的指数,它返回的总规模。 Therefore your main loop isn't actually doing anything, because length() returns 0 when the board is clear. 因此,您的主循环实际上没有执行任何操作,因为在清除木板时length()返回0。

With this change (and adding bounds checking to BitSetBoard.get() ), BitSetBoard runs in just under twice the time as ArrayBoard for me. 进行此更改(并在BitSetBoard.get()添加了边界检查),对我来说, BitSetBoard运行时间是ArrayBoard两倍。

BitSet is more memory efficient than boolean[] except for very small sizes for further clarification you can read BitSet比boolean []的存储效率更高,但其大小非常小,您可以阅读进一步澄清

boolean[] vs. BitSet: Which is more efficient? boolean []与BitSet:哪个更有效?

BitSet uses about 1 bit per boolean value, and boolean[] uses about 1 byte per boolean value. that also the case that BitSet are more efficient

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM