目录

一、使用场景

二、算法

1. Java-数组遍历

2. c/c++ -索引遍历

3. c/c++ -指针遍历

三、数据说话

四、总结


一、使用场景

    我们都知道不同的语言有不同的特性,所以在比较某一特性时,不同的语言会表现出差异。举个例子:我们都知道c/c++语言比Java的运行性能要高,但是具体高多少,其实我们心里是没有数的,那么本文章就是从一个简单的使用场景用数据来说话。

    在开发的过程中,我需要将16bit的pcm数据从双声道转换到单声道,随着pcm文件的增大,处理的时间随之增加,而这个处理时间太长,直接影响的用户体验,所以我决定使用不同的语言做以下对比,选用运行性能的语言来处理,并且对算法进行优化。

(在分析后面的算法之前还需要了解以下16bit pcm数据格式)

 

二、算法

1. Java-数组遍历

/**
     * pcm双声道转单声道
     *
     * @param inPath
     * @param outPath
     */
    public static boolean pcmStereo2Mono(String inPath, String outPath) {
        try {
            File file = new File(inPath);
            FileInputStream fis = new FileInputStream(file);
            int available = fis.available();
            byte[] data = new byte[available];
            byte[] data2 = new byte[available / 2];
            int read = fis.read(data, 0, available);
            for (int i = 0; i < available / 2; i++) {
                LogUtils.d(TAG, "");
                int t = i / 2 * 4 + i % 2;
                data2[i] = data[t];
            }

            File o = new File(outPath);
            o.createNewFile();
            FileOutputStream fos = new FileOutputStream(o);
            fos.write(data2);
            fos.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

2. c/c++ -索引遍历

//文件长度,根据实际情况进行赋值
    int fileLength = -1;
    //文件数据,根据实际情况进行赋值
    unsigned char * pFileBuf = new unsigned char[fileLength];

    int nOneChannelLen = fileLength / 2;
    unsigned char * pOneChannelBuf = new unsigned char[nOneChannelLen];
    //遍历方式1:数组索引
    for(int i = 0;i<nOneChannelLen;i++){
        int t = i / 2 * 4 + i % 2;
        pOneChannelBuf[i] = pFileBuf[t];
    }

3. c/c++ -指针遍历

//文件长度,根据实际情况进行赋值
    int fileLength = -1;
    //文件数据,根据实际情况进行赋值
    unsigned char * pFileBuf = new unsigned char[fileLength];

    int nOneChannelLen = fileLength / 2;
    unsigned char * pOneChannelBuf = new unsigned char[nOneChannelLen];
    //遍历方式2:指针
    for(int i = 0;i < nOneChannelLen/2;i++){
        (*pOneChannelBuf++) = (*pFileBuf++);
        (*pOneChannelBuf++) = (*pFileBuf++);
        pFileBuf = pFileBuf + 2;
    }
    //遍历之后一定要将指针复原,指回到缓冲区开始的位置,否则后面保存数据就会出错
    pFileBuf = pFileBuf - fileLength;
    pOneChannelBuf = pOneChannelBuf - nOneChannelLen;

 

三、数据说话

1.下面表格有三组数据,第一列是pcm语言文件的录制时长,第二列是对应pcm文件的文件大小,后面三列分别是用不同语言、不同算法,将16bit pcm文件从双声道转换到单声道所需要的时间,单位是ms。

语音时长(s)

文件大小(byte)

java(ms)

C++ -索引遍历 (ms)

C++ -指针遍历 (ms)

10

287360

6057

2901

1129

24

668800

14548

6636

2648

31

859520

17592

8080

3388

2.如果以Java语言的时间为基准,那么c++语言的处理时间与java语言处理的时间比之如下:

java(ms)

------------java(ms)

C++ -索引遍历 (ms)

------------------java(ms)

C++ -指针遍历 (ms)

------------------

java(ms)

100.00%

47.89%

18.64%

100.00%

45.61%

18.20%

100.00%

45.93%

19.26%

 

四、总结

   从以上数据可知,c/c++语言的处理效率要高于java语言,c/c++的指针访问的效率又高于索引访问的效率。