Source: http://git.oschina.net/SilentCode/JpegCodecs
性能分析: gprof main.exe > profile.txt
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
13.40 0.13 0.13 _spin_lite_unlock
12.37 0.25 0.12 std::string::compare(std::string const&)
12.37 0.37 0.12 _spin_lite_lock
10.31 0.47 0.10 __pthread_self_lite
9.28 0.56 0.09 std::_Rb_tree<std::string,
8.25 0.64 0.08 Transform(int*)
4.12 0.68 0.04 std::less<std::string>::operator()
3.09 0.71 0.03 std::_Rb_tree<std::string,
3.09 0.74 0.03 bool std::operator< <char,
3.09 0.77 0.03 __fpclassify
2.06 0.79 0.02 ConvertClrSpace
2.06 0.81 0.02 std::_Select1st
2.06 0.83 0.02 std::_Rb_tree_iterator
2.06 0.85 0.02 std::_Rb_tree
2.06 0.87 0.02 round
1.03 0.88 0.01 1 10.00 10.00 Encoder(unsigned char*, int, int, int&)
1.03 0.89 0.01 SetLastError@4
1.03 0.90 0.01 ComputeRealValue(int)
1.03 0.91 0.01 UpSample(int*, int*)
1.03 0.92 0.01 std::_Rb_tree
1.03 0.93 0.01 std::string
1.03 0.94 0.01 std::_Rb_tree
1.03 0.95 0.01 std::_Rb_tree
1.03 0.96 0.01 pthread_getspecific
1.03 0.97 0.01 pthread_setspecific
0.00 0.97 0.00 1 0.00 0.00 SetBitmapInfo(unsigned int, int, int)
0.00 0.97 0.00 1 0.00 0.00 Write(char const*, unsigned char*, int&)
0.00 0.97 0.00 1 0.00 0.00 Matrix()
可以看出,解码一张图片大约 1s 钟,而实际用于解码的时间不到 0.5s ,这是因为STL容器里面加入了很多安全与多线程相关的操作,这些额外的开销增加了解码的时间
下面是基于我实现的 tinyMap 解码后的结果:
Source:https://github.com/lzb-cc/JpegCodecs
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
23.73 0.14 0.14 48960 0.00 0.00 JpegDecoder::Transform(int*)
15.25 0.23 0.09 round
13.56 0.31 0.08 2092962 0.00 0.00 tinyMap::find(int)
10.17 0.37 0.06 8160 0.01 0.01 ConvertClrSpace(unsigned char*, int, int)
8.47 0.42 0.05 2333318 0.00 0.00 NextBit()
5.08 0.45 0.03 1 30.00 30.00 Encoder(unsigned char*, int, int, int&)
5.08 0.48 0.03 __fpclassify
3.39 0.50 0.02 48960 0.00 0.00 Dequant(int*, unsigned char*)
3.39 0.52 0.02 48960 0.00 0.00 UnZigZag(int*, int*)
3.39 0.54 0.02 16320 0.00 0.00 UpSample(int*, int*)
1.69 0.55 0.01 1776506 0.00 0.00 tinyStl::tinyMap::find(int, int)
1.69 0.56 0.01 316456 0.00 0.00 FindKeyValue(tinyStl::tinyMap&)
1.69 0.57 0.01 267496 0.00 0.00 ComputeRealValue(int)
1.69 0.58 0.01 48960 0.00 0.00 DecoderBlock
1.69 0.59 0.01 _spin_lite_lock
0.00 0.59 0.00 1776506 0.00 0.00 tinyStl::tinyMap::end()
0.00 0.59 0.00 316456 0.00 0.00 tinyStl::tinyMap::operator[](int)
0.00 0.59 0.00 26214 0.00 0.00 tinyStl::MapNode::Less(tinyStl::MapNode*)
0.00 0.59 0.00 8160 0.00 0.04 JpegCodec::JpegDecoder::DecoderMCU()
0.00 0.59 0.00 8160 0.00 0.00 FillYCbCr()
0.00 0.59 0.00 680 0.00 0.00 GrandParent(tinyStl::RBNode*)
0.00 0.59 0.00 348 0.00 0.00 RBNode()
0.00 0.59 0.00 348 0.00 0.00 Check1(tinyStl::RBNode*)
0.00 0.59 0.00 348 0.00 0.00 Insert(tinyStl::RBNode*)
0.00 0.59 0.00 348 0.00 0.00 insert(int, int, int)
0.00 0.59 0.00 344 0.00 0.00 Check2(tinyStl::RBNode*)
0.00 0.59 0.00 344 0.00 0.00 AddToTree(tinyStl::RBNode*, tinyStl::RBNode*)
0.00 0.59 0.00 340 0.00 0.00 RBTree::Uncle(tinyStl::RBNode*)
0.00 0.59 0.00 340 0.00 0.00 Check3(tinyStl::RBNode*)
0.00 0.59 0.00 340 0.00 0.00 Check4(tinyStl::RBNode*)
0.00 0.59 0.00 4 0.00 0.00 RBTree()
0.00 0.59 0.00 4 0.00 0.00 tinyMap()
0.00 0.59 0.00 4 0.00 0.00 ReBuildTable(int, tinyStl::tinyMap&)
0.00 0.59 0.00 3 0.00 0.00 MarkIndex(unsigned char)
0.00 0.59 0.00 1 0.00 0.00 SetBitmapInfo(unsigned int, int, int)
0.00 0.59 0.00 1 0.00 0.00 Write(char const*, unsigned char*, int&)
0.00 0.59 0.00 1 0.00 0.00 ComputeDHT()
0.00 0.59 0.00 1 0.00 0.00 ReadImageSize()
0.00 0.59 0.00 1 0.00 0.00 ToStartOfData()
0.00 0.59 0.00 1 0.00 0.00 ReadQuantTable()
0.00 0.59 0.00 1 0.00 430.00 Decoder(JpegCodec::Matrix&)
0.00 0.59 0.00 1 0.00 0.00 JpegDecoder(char const*)
0.00 0.59 0.00 1 0.00 0.00 ~JpegDecoder()
0.00 0.59 0.00 1 0.00 0.00 Create(int, int, int)
0.00 0.59 0.00 1 0.00 0.00 Matrix::Matrix()
与使用STL相比,性能有了明显的提升
测试代码:
// main.cpp
#include <stdio.h>
#include "JpegDecoder.h"
#include "BmpEncoder.h"
using namespace JpegCodec;
int main(int argc, char *argv[])
{
if (argc < 3)
{
printf("Usage: main input.jpg out.bmp\n");
return 0;
}
/* 解码 Jpeg 文件 */
JpegDecoder decoder(argv[1]);
Matrix mat;
decoder.Decoder(mat);
/* 保存为 Bitmap 格式图像 */
int size;
unsigned char *bitmap = Encoder(mat.data, mat.rows, mat.cols, size);
Write(argv[2], bitmap, size);
return 0;
}