算法优化之算法一

作者在检查代码时发现可优化之处,指出平时开发中修改源码能提升程序性能。以read方法为例,原本循环new byte[]接收数据存在问题,修改源码后用同一个byte[]接收,优化了while循环。此类优化可用于串口接收数据,减少资源消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在检查回顾代码时,发现了一个可优化的地方,同时想到在平时的开发中很多细微处我们通过对源码的稍微修改是可以提升程序的运行速度和性能的。话不多说,看代码。

  private class ReadThread extends Thread {
        private boolean isRun; //是否一直循环

        @Override
        public synchronized void start() {
            isRun = true;
            super.start();
        }

        private void stopRun() {
            isRun = false;
            interrupt();
        }

        @Override
        public void run() {
            super.run();
            //判断进程是否在运行,更安全的结束进程
            try {
                while (isRun) {
                    byte[] buffer = new byte[100];
                    int size; //读取数据的大小
                    size = getSerialPort().getInputStream().read(buffer);
                    if (size > 32) {
                        String str = new String(buffer, 0, size).trim();
                        //传输的数据是数据加 空数据间隔 传送
                        if (!TextUtils.isEmpty(str)) {
//                          MyLog.myInfo("收到的数据" + str);
                            if (handler != null) {
                                Message msg = handler.obtainMessage(WEIGHT_NOTIFY_XS15, str);
                                handler.sendMessage(msg);
                            }
                        }
                    }
                    Thread.sleep(150);
                }
            } catch (IOException e) {
                Log.e(TAG, "run: 数据读取异常:" + e.toString());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
 上面的代码是我的原始代码,这是一个硬件的数据读取,需要循环读取串口数据,这时我发现代码有个地方是不合理的
while (isRun) {
    byte[] buffer = new byte[100];
    int size; //读取数据的大小
    size = getSerialPort().getInputStream().read(buffer);
这个地方是不合理的,我觉得在while循环中不断的创建byte[],然后将串口中读取到的数据赋值其中。于是翻开 InputStream.read(byte b[]):
 public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
 }
public int read(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

        int c = read();
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;

        int i = 1;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }

很明显 read(byte b[], int off, int len) 就是将你不断new byte[]的数组赋值,当无数据了后面默认补充为0。现在我知道我每次循环读的数据最长byte[]长度是60,然后有多种类型的数据,byte[]长度为 7 ,24, 32,53是代表不通含义的数据。我想用一个byte[]创建一次接收数据,不用循环new byte[]。那么用源码,你会发现如果第一次接收53长度的数据后,再接收byte[]长度7的数据,这是索引Index以后的数据不再是0而是53长度时的数据,这样和原本数据肯定不一样,不符合要求。所以对源码进行修改。

/***
 * 称重的有效数据 一般是 57位
 *
 * @param b  源数组
 * @param off  起始位置
 * @param len  数组 b 的数据长度length
 * @return     返回InputStream 中的byte 数据长度
 * @throws IOException  抛出的异常
 */
//TODO 待 移动到base类中
public synchronized  int read(byte b[], int off, int len) throws IOException {
    if (b == null) {
        throw new NullPointerException();
    } else if (off < 0 || len < 0 || len > b.length - off) {
        throw new IndexOutOfBoundsException();
    } else if (len == 0) {
        return 0;
    }

    int c = getSerialPortPrinter().getInputStream().read();
    if (c == -1) {
        return -1;
    }
    b[off] = (byte) c;
    int i = 1;
    int size=1;
    //数据是否完了
    boolean isOver = false;
    try {
        for (; i < len; i++) {
            c = getSerialPortPrinter().getInputStream().read();
            if (c == -1) {
                isOver=true;
            }
            if(isOver){
                b[off + i] =  0;
            }else {
                b[off + i] = (byte) c;
                if(c!=0){
                    size++;
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return size;
}

通过上面的代码修改,这样每次用同一个byte[]就能接收原滋原味的数据,不用反复new byte[]。我想这对于while循环优化了不少吧。

  private class ReadThread extends Thread {
        private boolean isRun; //是否一直循环

        @Override
        public synchronized void start() {
            isRun = true;
            super.start();
        }

        private void stopRun() {
            isRun = false;
            interrupt();
        }

        @Override
        public void run() {
            byte[] buffer = new byte[60];
            super.run();
            //判断进程是否在运行,更安全的结束进程
            try {
                while (isRun) {
                    int size; //读取数据的大小
                    size = read(buffer,0,buffer.length);
                    String str = new String(buffer, 0, size).trim();
                    Thread.sleep(120);
                }
            } catch (IOException e) {
                Log.e(TAG, "run: 数据读取异常:" + e.toString());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

好了上面就是对代码的一个小优化。在编码的过程中,我们是可以尝试对源码进行修改以符合自己的需要的,这样以少积多,就能对代码及系统有个巨大的提升。

这类优化可以在串口接收数据方面应用,很多需要从串口不断接收数据的程序都有一个while 循环不断new byte[]接收,很费资源。

上面是个人的体会积累,如有缺陷,请多指教。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值