從雙聲道轉單聲道看語言/算法性能差異

目錄

一、使用場景

二、算法

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++的指針訪問的效率又高於索引訪問的效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章