目錄
一、使用場景
我們都知道不同的語言有不同的特性,所以在比較某一特性時,不同的語言會表現出差異。舉個例子:我們都知道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++的指針訪問的效率又高於索引訪問的效率。