Я пишу фрагмент кода, предназначенный для сжатия данных в структурах CLSID. Я храню их как сжатый поток из 128-битных целых чисел. Однако рассматриваемый код должен иметь возможность помещать недопустимые идентификаторы CLSID в поток. Чтобы сделать это, я оставил их как одну большую строку. На диске это будет выглядеть примерно так:
+--------------------------+-----------------+------------------------+
| | | |
| Length of Invalid String | Invalid String | Compressed Data Stream |
| | | |
+--------------------------+-----------------+------------------------+
Чтобы закодировать длину строки, мне нужно вывести 32-разрядное целое число, которое является длиной строки по одному байту за раз. Вот мой текущий код:
std::vector<BYTE> compressedBytes;
DWORD invalidLength = (DWORD) invalidClsids.length();
compressedBytes.push_back((BYTE) invalidLength & 0x000000FF);
compressedBytes.push_back((BYTE) (invalidLength >>= 8) & 0x000000FF));
compressedBytes.push_back((BYTE) (invalidLength >>= 8) & 0x000000FF));
compressedBytes.push_back((BYTE) (invalidLength >>= 8));
Этот код будет вызываться не часто, но на этапе декодирования потребуется аналогичная структура, которая вызывается много тысяч раз. Мне любопытно, если это самый эффективный метод или кто-то может придумать один лучше?
Спасибо всем!
Billy3
EDIT:
Изучив некоторые ответы, я создал эту мини-тестовую программу, чтобы увидеть, какая из них была самой быстрой:
// temp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <ctime>
#include <iostream>
#include <vector>
void testAssignedShifts();
void testRawShifts();
void testUnion();
int _tmain(int argc, _TCHAR* argv[])
{
std::clock_t startTime = std::clock();
for (register unsigned __int32 forLoopTest = 0; forLoopTest < 0x008FFFFF; forLoopTest++)
{
testAssignedShifts();
}
std::clock_t assignedShiftsFinishedTime = std::clock();
for (register unsigned __int32 forLoopTest = 0; forLoopTest < 0x008FFFFF; forLoopTest++)
{
testRawShifts();
}
std::clock_t rawShiftsFinishedTime = std::clock();
for (register unsigned __int32 forLoopTest = 0; forLoopTest < 0x008FFFFF; forLoopTest++)
{
testUnion();
}
std::clock_t unionFinishedTime = std::clock();
std::printf(
"Execution time for assigned shifts: %08u clocks\n"
"Execution time for raw shifts: %08u clocks\n"
"Execution time for union: %08u clocks\n\n",
assignedShiftsFinishedTime - startTime,
rawShiftsFinishedTime - assignedShiftsFinishedTime,
unionFinishedTime - rawShiftsFinishedTime);
startTime = std::clock();
for (register unsigned __int32 forLoopTest = 0; forLoopTest < 0x008FFFFF; forLoopTest++)
{
testAssignedShifts();
}
assignedShiftsFinishedTime = std::clock();
for (register unsigned __int32 forLoopTest = 0; forLoopTest < 0x008FFFFF; forLoopTest++)
{
testRawShifts();
}
rawShiftsFinishedTime = std::clock();
for (register unsigned __int32 forLoopTest = 0; forLoopTest < 0x008FFFFF; forLoopTest++)
{
testUnion();
}
unionFinishedTime = std::clock();
std::printf(
"Execution time for assigned shifts: %08u clocks\n"
"Execution time for raw shifts: %08u clocks\n"
"Execution time for union: %08u clocks\n\n"
"Finished. Terminate!\n\n",
assignedShiftsFinishedTime - startTime,
rawShiftsFinishedTime - assignedShiftsFinishedTime,
unionFinishedTime - rawShiftsFinishedTime);
system("pause");
return 0;
}
void testAssignedShifts()
{
std::string invalidClsids("This is a test string");
std::vector<BYTE> compressedBytes;
DWORD invalidLength = (DWORD) invalidClsids.length();
compressedBytes.push_back((BYTE) invalidLength);
compressedBytes.push_back((BYTE) (invalidLength >>= 8));
compressedBytes.push_back((BYTE) (invalidLength >>= 8));
compressedBytes.push_back((BYTE) (invalidLength >>= 8));
}
void testRawShifts()
{
std::string invalidClsids("This is a test string");
std::vector<BYTE> compressedBytes;
DWORD invalidLength = (DWORD) invalidClsids.length();
compressedBytes.push_back((BYTE) invalidLength);
compressedBytes.push_back((BYTE) (invalidLength >> 8));
compressedBytes.push_back((BYTE) (invalidLength >> 16));
compressedBytes.push_back((BYTE) (invalidLength >> 24));
}
typedef union _choice
{
DWORD dwordVal;
BYTE bytes[4];
} choice;
void testUnion()
{
std::string invalidClsids("This is a test string");
std::vector<BYTE> compressedBytes;
choice invalidLength;
invalidLength.dwordVal = (DWORD) invalidClsids.length();
compressedBytes.push_back(invalidLength.bytes[0]);
compressedBytes.push_back(invalidLength.bytes[1]);
compressedBytes.push_back(invalidLength.bytes[2]);
compressedBytes.push_back(invalidLength.bytes[3]);
}
Выполнение этого несколько раз приводит к:
Execution time for assigned shifts: 00012484 clocks
Execution time for raw shifts: 00012578 clocks
Execution time for union: 00013172 clocks
Execution time for assigned shifts: 00012594 clocks
Execution time for raw shifts: 00013140 clocks
Execution time for union: 00012782 clocks
Execution time for assigned shifts: 00012500 clocks
Execution time for raw shifts: 00012515 clocks
Execution time for union: 00012531 clocks
Execution time for assigned shifts: 00012391 clocks
Execution time for raw shifts: 00012469 clocks
Execution time for union: 00012500 clocks
Execution time for assigned shifts: 00012500 clocks
Execution time for raw shifts: 00012562 clocks
Execution time for union: 00012422 clocks
Execution time for assigned shifts: 00012484 clocks
Execution time for raw shifts: 00012407 clocks
Execution time for union: 00012468 clocks
Похоже, что есть связь между назначенными сменами и объединением. Поскольку значение мне понадобится позже, объединение это! Спасибо!
Billy3