如何做到性能优化?

时间换空间,空间换时间

Posted by MasterJen on November 17, 2018

Hey 时间,空间

Wasting time is robbing oneself.–浪费时间就是掠夺自己.

什么时候时间换空间? 时间换空间常用于内存、硬盘空间不足的情况下,通过牺牲CPU的方式获得原本需要更多内存或者硬盘空间才能完成的工作.

简单的时间换空间 例子 两个数的互换  
    a = a+b;
    b = a-b;
    a = a-b;
 另外的例子就是对 无符号整数的支持
 
    public class UnsignedByte {
        public short getValue(byte i) {
    //        将 byte 转换为  short
            return (short) (i & 0xff);
        }
    
        public byte toUnsignedByte(short i) {
    //        将 short 转换为  byte
            return (byte) (i & 0xff);
        }
    
        public static void main(String[] args) {
            UnsignedByte ins = new UnsignedByte();
    //       创建 short数组  上限是byte的上限
            short[] shorts = new short[256];
    //        存储 short 数组
            for (int i = 0; i < shorts.length; i++)
                shorts[i] = (short) i;
    //      创建 byte数组  替代 short 数组
            byte[] bytes = new byte[256];
            for (int i = 0; i < bytes.length; i++)
                ins.toUnsignedByte(shorts[i]);
    //       从 byte数组中得到 short 数组    完成了 时间换空间  
            for (int i = 0; i < bytes.length; i++) {
                System.out.println(ins.getValue(bytes[i]) + "-->");
            }       
        } 

空间换时间 尝试使用更多的内存或者磁盘空间换取CPU资源或者网络资源,通过增加系统的内存消耗,来加快程序的运行速度.

典型的就是 空间换时间排序算法

public class SpaceSort {
    public static int arrayLen = 1000000;

    public static void main(String[] args) {
        int[] a = new int[arrayLen];
        int[] old = new int[arrayLen];
        Map<Integer, Object> map = new HashMap<>();
        int count = 0;
//          初始化数据
        while (count < a.length) {
//              得到随机数
            int value = (int) (Math.random() * arrayLen * 10) + 1;
//              判断map有没有值
            if (map.get(value) == null) {
//                  把 值value 放到 map中
                map.put(value, value);
//                  给数组赋值
                a[count] = value;
                count++;
            }
        }
//          保存原有数据
        System.arraycopy(a, 0, old, 0, a.length);
        long start = System.currentTimeMillis();
        Arrays.sort(a);
        System.out.println("传统 Arrays的排序时间===" + (System.currentTimeMillis() - start) + "--ms");
//           回复原有数据
        System.arraycopy(old, 0, a, 0, old.length);
        start = System.currentTimeMillis();
        spaceToTime(a);
        System.out.println("使用空间机制的排序时间===" + (System.currentTimeMillis() - start) + "--ms");

    }

    /**
     *  以 空间  换取 时间  ,不惜代价的使用空间
     * @param array
     */
    private static void spaceToTime(int[] array) {
        int i = 0;
        int max = array[0];
        int len = array.length;
//        找出最大值
        for (i = 1; i < len; i++)
            if (array[i] > max) {
                max = array[i];
            }
//            分配临时空间
        int[] temp = new int[max+1];
//            以 索引下标 来标志数字大小
        for (i = 0; i < len; i++)
            temp[array[i]] = array[i];
        int j = 0;
        int max1 = max+1;
//        线程复杂度
        for ( i = 0; i < max1; i++) {
            if(temp[i]>0){
                array[j++] = temp[i];
            }
        }
    }
}

对 100W 数据进行排序 时间结果如下 ​
传统 Arrays的排序时间===312–ms 使用空间机制的排序时间===64–ms

相差的时间很大.