C++文件轉base64字符串的代碼_從網上抄了些_但我作了優化_1G數據從9秒優化到了1秒

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

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

2.使用char* 代替string 對象數組


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


關鍵代碼: FileDataToBase64String 這個函數有個char*版本fetch

#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::endl;
	}
}
相關文章
相關標籤/搜索