1. 程式人生 > >C++檔案轉base64字串的程式碼_從網上抄了些_但我做了優化_1G資料從9秒優化到了1秒

C++檔案轉base64字串的程式碼_從網上抄了些_但我做了優化_1G資料從9秒優化到了1秒

程式碼執行效率優化的幾個關鍵點: 1.使用一個編碼陣列, 解決掉編碼中的一些判斷與加減運算

//編碼表  
const static char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

2.使用char* 代替string 物件


示例備份: https://pan.baidu.com/s/1tfMNne6bkvg8GYDCTdhpfw s3tx


關鍵程式碼: FileDataToBase64String 這個函式有個char*版本

#include "pch.h"
#include "FileDataToBase64String.h"

namespace FileDataToBase64String0507
{


//編碼表  
const static char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static uint8_t  encode(int value)
{
	return EncodeTable[value & 0x3f];
}

}

void FileDataToBase64String(const uint8_t* const input, std::string &out, size_t srcSize)
{
	using namespace FileDataToBase64String0507;
	{
		out.clear();

		size_t i, value;

		//step1:
		size_t equal_count = (3 - srcSize % 3) % 3;// 0或1或2  // 需補等號的數目
		size_t count333 = srcSize - (3 - equal_count);// 

		size_t stringSize = srcSize * 1.4;
		//std::cout << "原檔案大小:" << srcSize << "預計轉後大小:" << stringSize << "大小計算2:" << count333/3*4+ equal_count << std::endl;
		//out.resize(stringSize);

		for (i = 0; i < count333;) {
			value = input[i++] << 16;
			value |= input[i++] << 8;
			value |= input[i++];

			out += encode(value >> 18);
			out += encode(value >> 12);
			out += encode(value >> 6);
			out += encode(value);
		}

		switch (equal_count)
		{
		case 2:
			value = input[i++] << 16; /* fetch first byte */
			out += encode(value >> 18);
			out += encode(value >> 12);
			out += "==";
			break;
		case 1:
			value = input[i++] << 16; /* fetch first byte */
			value |= input[i++] << 8; 
			out += encode(value >> 18);
			out += encode(value >> 12);
			out += encode(value >> 6);
			out += "=";
			break;
		}
	}
	
	//std::cout << "最後字串大小:" << out.size() <<"\tlength:"<< out.length() << std::endl;
}


void FileDataToBase64String(const uint8_t* const input, char* &out, size_t srcSize)
{
	using namespace FileDataToBase64String0507;
	{
		size_t i, value;

		//step1:
		size_t equal_count_2 = srcSize % 3;// 0或1或2  // 需補等號的數目
		size_t count333 = srcSize - equal_count_2;// 

		size_t stringIndex = 0;
		size_t stringAllocate = (count333 / 3 + 1) * 4;
		out = (char*)malloc(stringAllocate);
		//std::cout << "分配給字串的記憶體大小:"<< stringAllocate <<"\t之前錯的演算法是:"<< (count333 + 1) / 3 * 4 << std::endl;

		for (i = 0; i < count333; i += 3) {
			value = input[i] << 16 | input[i+1] << 8  | input[i+2];
			
			out[stringIndex++] = EncodeTable[value >> 18 & 0x3f]; // encode(value >> 18);
			out[stringIndex++] = EncodeTable[value >> 12 & 0x3f]; // encode(value >> 12);
			out[stringIndex++] = EncodeTable[value >> 6 & 0x3f];  // encode(value >> 6);
			out[stringIndex++] = EncodeTable[value & 0x3f];		  // encode(value);
		}

		switch (equal_count_2)
		{
		case 1:// 從2改成1 意義是: 除3餘1的情況下, 需補兩等號
			value = input[i++]; /* fetch first byte */
			out[stringIndex++] = encode(value >> 6);
			out[stringIndex++] = encode(value);
			out[stringIndex++] = '=';
			out[stringIndex++] = '=';
			break;
		case 2:
			value = input[i++] << 8; /* fetch first byte */
			value |= input[i++] ;
			out[stringIndex++]= encode(value >> 12);
			out[stringIndex++]= encode(value >> 6);
			out[stringIndex++]= encode(value);
			out[stringIndex++]= '=';
			break;
		}

		//std::cout << "最後,字串所佔記憶體:" << stringIndex << std: