目录
一、使用场景
我们都知道不同的语言有不同的特性,所以在比较某一特性时,不同的语言会表现出差异。举个例子:我们都知道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++的指针访问的效率又高于索引访问的效率。