CLSID 構造体でデータ圧縮を行うように設計されたコードを書いています。それらを 128 ビット整数の圧縮ストリームとして保存しています。ただし、問題のコードは、無効な CLSID をストリームに配置できる必要があります。これを行うために、それらを 1 つの大きな文字列として残しました。ディスク上では、次のようになります。
+--------------------------+-----------------+------------------------+
| | | |
| Length of Invalid String | Invalid String | Compressed Data Stream |
| | | |
+--------------------------+-----------------+------------------------+
文字列の長さをエンコードするには、文字列の長さである 32 ビット整数を一度に 1 バイトずつ出力する必要があります。これが私の現在のコードです:
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));
このコードは頻繁に呼び出されるわけではありませんが、デコード段階で何千回も呼び出される同様の構造が必要になります。これが最も効率的な方法なのか、それとも誰かがより良い方法を思いつくことができるのか、興味がありますか?
皆さんありがとう!
ビリー3
編集:いくつかの回答を調べた後、このミニテストプログラムを作成して、どれが最速かを確認しました:
// 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
割り当てられたシフトと組合の間のタイについてのように見えます。後で値が必要になるので、union です! ありがとう!
ビリー3