[LIBGDX学习]LibGDX代码详解(二十五)Buffer测试

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;

import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.mygdx.game.utils.GdxTest;
import com.badlogic.gdx.utils.BufferUtils;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.badlogic.gdx.utils.TimeUtils;

/**
 * BufferUtils:
 * Class with static helper methods to increase the speed
 * of array/direct buffer and direct buffer/direct buffer transfers

 */
public class BufferUtilsTest extends GdxTest {
    //static final int NUM_MB = 5;
    static final int NUM_MB = 10000;

    @Override
    public void create () {
        //Not emulated in gwt
        //ByteBuffer bytebuffer = BufferUtils.newUnsafeByteBuffer(1000 * 1000);
        //BufferUtils.disposeUnsafeByteBuffer(bytebuffer);

        ByteBuffer bb = BufferUtils.newByteBuffer(8);
        CharBuffer cb = BufferUtils.newCharBuffer(8);
        ShortBuffer sb = BufferUtils.newShortBuffer(8);
        IntBuffer ib = BufferUtils.newIntBuffer(8);
        LongBuffer lb = BufferUtils.newLongBuffer(8);
        FloatBuffer fb = BufferUtils.newFloatBuffer(8);
        DoubleBuffer db = BufferUtils.newDoubleBuffer(8);

        // position():Sets this buffer's position.
        // If the mark is defined and larger than the new position then it is discarded.
        bb.position(4);

        // BufferUtilsTest: checkInt failed: 4 != 1
        //bb.position(1);// 果然报错了

        BufferUtils.copy(new byte[] {1, 2, 3, 4}, 0, bb, 4);

        // get():Relative get method. Reads the byte at this
        // buffer's current position, and then increments the position.
        checkInt(bb.get(), 1);
        checkInt(bb.get(), 2);
        checkInt(bb.get(), 3);
        checkInt(bb.get(), 4);

        // char buffer
        cb.position(4);
        BufferUtils.copy(new char[] {1, 2, 3, 4}, 0, cb, 4);
        checkInt(cb.get(), 1);
        checkInt(cb.get(), 2);
        checkInt(cb.get(), 3);
        checkInt(cb.get(), 4);
        cb.position(0);
        BufferUtils.copy(new char[] {5, 6, 7, 8}, 1, cb, 3);
        checkInt(cb.get(), 6);
        checkInt(cb.get(), 7);
        checkInt(cb.get(), 8);

        // short buffer
        sb.position(4);
        BufferUtils.copy(new short[] {1, 2, 3, 4}, 0, sb, 4);
        checkInt(sb.get(), 1);
        checkInt(sb.get(), 2);
        checkInt(sb.get(), 3);
        checkInt(sb.get(), 4);
        sb.position(0);
        BufferUtils.copy(new short[] {5, 6, 7, 8}, 1, sb, 3);
        checkInt(sb.get(), 6);
        checkInt(sb.get(), 7);
        checkInt(sb.get(), 8);

        // int buffer
        ib.position(4);
        BufferUtils.copy(new int[] {1, 2, 3, 4}, 0, ib, 4);
        checkInt(ib.get(), 1);
        checkInt(ib.get(), 2);
        checkInt(ib.get(), 3);
        checkInt(ib.get(), 4);
        ib.position(0);
        BufferUtils.copy(new int[] {5, 6, 7, 8}, 1, ib, 3);
        checkInt(ib.get(), 6);
        checkInt(ib.get(), 7);
        checkInt(ib.get(), 8);

        // long buffer
        lb.position(4);
        BufferUtils.copy(new long[] {1, 2, 3, 4}, 0, lb, 4);
        checkInt(lb.get(), 1);
        checkInt(lb.get(), 2);
        checkInt(lb.get(), 3);
        checkInt(lb.get(), 4);
        lb.position(0);
        BufferUtils.copy(new long[] {5, 6, 7, 8}, 1, lb, 3);
        checkInt(lb.get(), 6);
        checkInt(lb.get(), 7);
        checkInt(lb.get(), 8);

        // float buffer
        fb.position(4);
        BufferUtils.copy(new float[] {1, 2, 3, 4}, 0, fb, 4);
        checkFloat(fb.get(), 1);
        checkFloat(fb.get(), 2);
        checkFloat(fb.get(), 3);
        checkFloat(fb.get(), 4);
        fb.position(0);
        BufferUtils.copy(new float[] {5, 6, 7, 8}, 1, fb, 3);
        checkFloat(fb.get(), 6);
        checkFloat(fb.get(), 7);
        checkFloat(fb.get(), 8);

        // WebGL 就是HTML5环境?
        if (Gdx.app.getType() != ApplicationType.WebGL) { // gwt throws: NYI: Numbers.doubleToRawLongBits
            db.position(4);
            BufferUtils.copy(new double[] {1, 2, 3, 4}, 0, db, 4);
            checkFloat(db.get(), 1);
            checkFloat(db.get(), 2);
            checkFloat(db.get(), 3);
            checkFloat(db.get(), 4);
            db.position(0);
            BufferUtils.copy(new double[] {5, 6, 7, 8}, 1, db, 3);
            checkFloat(db.get(), 6);
            checkFloat(db.get(), 7);
            checkFloat(db.get(), 8);
        }

        ByteBuffer bb2 = BufferUtils.newByteBuffer(4);
        bb.position(4);
        BufferUtils.copy(bb, bb2, 4);
        checkInt(bb2.get(), 1);
        checkInt(bb2.get(), 2);
        checkInt(bb2.get(), 3);
        checkInt(bb2.get(), 4);

        bench();
    }

    private void bench () {
        benchByte();
        benchShort();
        benchInt();
        benchLong();
        benchFloat();
        benchDouble();
    }

    // 比较速度测试,这种模式可以用在很多地方,比如比较不同算法的速度。
    private void benchByte () {
        ByteBuffer bb = BufferUtils.newByteBuffer(1024 * 1024);

        // BufferUtilsTest Jacob: ByteBuffer relative put: 3.8047454
        // BufferUtilsTest: ByteBuffer absolute put: 2.7288485
        // BufferUtilsTest: ByteBuffer bulk put: 1.3173847
        //ByteBuffer bb = BufferUtils.newByteBuffer(1024 * 1024*1024);

        byte[] bytes = new byte[1024 * 1024];
        //byte[] bytes = new byte[1024 * 1024*1024];
        int len = bytes.length;
        //final int NUM_MB = 5;
        final int NUM_MB = 20000;// 设置一个数延长测试时间?

        // relative put
        long start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            bb.clear();
            for (int i = 0; i < len; i++)
                // Writes the given byte into this buffer at the current position,
                // and then increments the position.
                bb.put(bytes[i]);
            //System.out.println(len);//1048576
        }
        // 桌面程序也显示。。。
        Gdx.app.log("BufferUtilsTest Jacob", "ByteBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // absolute put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            bb.clear();
            for (int i = 0; i < len; i++)
                // Writes the given byte into this buffer at the given index.
                bb.put(i, bytes[i]);
        }
        Gdx.app.log("BufferUtilsTest", "ByteBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // bulk put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            bb.clear();
            bb.put(bytes);
        }
        Gdx.app.log("BufferUtilsTest", "ByteBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // JNI put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            bb.clear();
            BufferUtils.copy(bytes, 0, bb, len);// 为何会比上面的慢一倍?
        }
        Gdx.app.log("BufferUtilsTest", "ByteBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
    }

    private void benchShort () {
        ShortBuffer sb = BufferUtils.newShortBuffer(1024 * 1024 / 2);
        short[] shorts = new short[1024 * 1024 / 2];
        int len = shorts.length;

        // relative put
        long start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            sb.clear();
            for (int i = 0; i < len; i++)
                sb.put(shorts[i]);
        }
        Gdx.app.log("BufferUtilsTest", "ShortBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // absolute put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            sb.clear();
            for (int i = 0; i < len; i++)
                sb.put(i, shorts[i]);// 这里时间差和bulk put比有点夸张
        }
        Gdx.app.log("BufferUtilsTest", "ShortBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // bulk put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            sb.clear();
            sb.put(shorts);
        }
        Gdx.app.log("BufferUtilsTest", "ShortBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // JNI put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            sb.clear();
            BufferUtils.copy(shorts, 0, sb, len);
        }
        Gdx.app.log("BufferUtilsTest", "ShortBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
    }

    private void benchInt () {
        IntBuffer ib = BufferUtils.newIntBuffer(1024 * 1024 / 4);
        int[] ints = new int[1024 * 1024 / 4];
        int len = ints.length;

        // relative put
        long start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            ib.clear();
            for (int i = 0; i < len; i++)
                ib.put(ints[i]);
        }
        Gdx.app.log("BufferUtilsTest", "IntBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // absolute put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            ib.clear();
            for (int i = 0; i < len; i++)
                ib.put(i, ints[i]);
        }
        Gdx.app.log("BufferUtilsTest", "IntBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // bulk put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            ib.clear();
            ib.put(ints);
        }
        Gdx.app.log("BufferUtilsTest", "IntBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // JNI put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            ib.clear();
            BufferUtils.copy(ints, 0, ib, len);
        }
        Gdx.app.log("BufferUtilsTest", "IntBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
    }

    private void benchLong () {
        LongBuffer lb = BufferUtils.newLongBuffer(1024 * 1024 / 8);
        long[] longs = new long[1024 * 1024 / 8];
        int len = longs.length;

        // relative put
        long start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            lb.clear();
            for (int i = 0; i < len; i++)
                lb.put(longs[i]);
        }
        Gdx.app.log("BufferUtilsTest", "LongBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // absolute put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            lb.clear();
            for (int i = 0; i < len; i++)
                lb.put(i, longs[i]);
        }
        Gdx.app.log("BufferUtilsTest", "LongBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // bulk put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            lb.clear();
            lb.put(longs);
        }
        Gdx.app.log("BufferUtilsTest", "LongBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // JNI put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            lb.clear();
            BufferUtils.copy(longs, 0, lb, len);
        }
        Gdx.app.log("BufferUtilsTest", "LongBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
    }

    private void benchFloat () {
        FloatBuffer fb = BufferUtils.newFloatBuffer(1024 * 1024 / 4);
        float[] floats = new float[1024 * 1024 / 4];
        int len = floats.length;

        // relative put
        long start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            fb.clear();
            for (int i = 0; i < len; i++)
                fb.put(floats[i]);
        }
        Gdx.app.log("BufferUtilsTest", "FloatBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // absolute put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            fb.clear();
            for (int i = 0; i < len; i++)
                fb.put(i, floats[i]);
        }
        Gdx.app.log("BufferUtilsTest", "FloatBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // bulk put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            fb.clear();
            fb.put(floats);
        }
        Gdx.app.log("BufferUtilsTest", "FloatBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // JNI put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            fb.clear();
            BufferUtils.copy(floats, 0, fb, len);
        }
        Gdx.app.log("BufferUtilsTest", "FloatBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
    }

    private void benchDouble () {
        DoubleBuffer db = BufferUtils.newDoubleBuffer(1024 * 1024 / 8);
        double[] doubles = new double[1024 * 1024 / 8];
        int len = doubles.length;

        // relative put
        long start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            db.clear();
            for (int i = 0; i < len; i++)
                db.put(doubles[i]);
        }
        Gdx.app.log("BufferUtilsTest", "DoubleBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // absolute put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            db.clear();
            for (int i = 0; i < len; i++)
                db.put(i, doubles[i]);
        }
        Gdx.app.log("BufferUtilsTest", "DoubleBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // bulk put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            db.clear();
            db.put(doubles);
        }
        Gdx.app.log("BufferUtilsTest", "DoubleBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);

        // JNI put
        start = TimeUtils.nanoTime();
        for (int j = 0; j < NUM_MB; j++) {
            db.clear();
            BufferUtils.copy(doubles, 0, db, len);
        }
        Gdx.app.log("BufferUtilsTest", "DoubleBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
    }

    private void checkInt (long val1, long val2) {
        if (val1 != val2) {
            Gdx.app.error("BufferUtilsTest", "checkInt failed: "+val1+" != "+val2);
            throw new GdxRuntimeException("Error, val1 != val2");
        }
    }

    private void checkFloat (double val1, double val2) {
        if (val1 != val2) {
            Gdx.app.error("BufferUtilsTest", "checkFloat failed: "+val1+" != "+val2);
            throw new GdxRuntimeException("Error, val1 != val2");
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值