Qualsiasi for può essere sostituito da un corrispondente while - e viceversa. Ed è improbabile che uno di questi costrutti sia chiaramente più economico dell'altro.
Mathemat: Qualsiasi for può essere sostituito da un corrispondente while - e viceversa. Ed è improbabile che uno di questi costrutti sia chiaramente più economico dell'altro.
Qualsiasi for e while può essere sostituito da goto con un'esecuzione più veloce del codice.
Mathemat: Un esempio, Vadim? Non datemi asm, datemi qualcosa in C.
// 1.1.1. Метод копирования данных по указателю до 128 Гб.
template<class type1, class type2> // Любые типы.staticvoid Copy( type1* pt1Dest, // Указатель на приёмник данных.const DWORD64 dw64SizeDest, // Размер приёмника данных в байтах.
type2* pt2Source, // Указатель на источник данных.const DWORD64 dw64SizeSource, // Размер источника данных в байтах, начиная от указателя pt2Source.
DWORD64 dw64Count) // Количество копируемых данных в байтах.
{
PBYTE pbtDest = PBYTE(pt1Dest); // Инициализируем локальный указатель на приёмник.
PBYTE pbtSource = PBYTE(pt2Source); // Инициализируем локальный указатель на источник.// Корректируем количество копируемых байт под размер источника.
dw64Count = COUNT_DIRECT(_T("Utils::Memory::Simple::Copy"), dw64SizeSource, 0, dw64Count);
dw64Count = Min(dw64Count, dw64SizeDest);
// Для количества данных более или равно 2147483647 байт цикл необходим.if (dw64Count >= sizeof(BYTES_0X7FFFFFFF))
{
DWORD64 i = 0;
DWORD64 dw64Iterations = Utils::Math::Arithmetic::DivideFloor(dw64Count, sizeof(BYTES_0X7FFFFFFF)); // Количество итераций. Округляем в меньшую сторону.
START: if (!SimpleCopy<BYTES_0X7FFFFFFF>(pbtDest, pbtSource, dw64Count)) return;
i++;
if (i < dw64Iterations) goto START;
}
if (!SimpleCopy<BYTES_0X40000000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X20000000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X10000000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X8000000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X4000000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X2000000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X1000000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X800000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X400000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X200000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X100000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X80000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X40000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X20000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X10000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X8000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X4000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X2000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X1000>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X800>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X400>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X200>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X100>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X80>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X40>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X20>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X10>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X8>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X4>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X2>(pbtDest, pbtSource, dw64Count)) return;
if (!SimpleCopy<BYTES_0X1>(pbtDest, pbtSource, dw64Count)) return;
}
Ho cercato di sbarazzarmi dei loop non necessari. Questo codice funziona il 20% più velocemente di memcpy standard. Inoltre non limita la dimensione della copia ed è più sicuro di memcpy.
Grazie. Per quanto ho capito, la costruzione principale che dovrebbe funzionare più velocemente è questa:
START: if (!SimpleCopy<BYTES_0X7FFFFFFF>(pbtDest, pbtSource, dw64Count)) return;
i++;
if (i < dw64Iterations) goto START;
Bene, questa è l'emulazione. Sì, è abbastanza possibile che sia più veloce del ciclo standard. Ma probabilmente solo a spese di un tempo di inizializzazione più lento del costrutto di controllo stesso.
goto è molto versatile. Sostituisce per un po' e si rompe. È molto meglio uscire da un ciclo goto multiplo annidato che aggiungere una condizione di interruzione ad ogni ciclo annidato.
Qualsiasi for può essere sostituito da un corrispondente while - e viceversa. Ed è improbabile che uno di questi costrutti sia chiaramente più economico dell'altro.
Un esempio, Vadim? Non datemi asm, datemi qualcosa in C.
Grazie. Per quanto ho capito, la costruzione principale che dovrebbe funzionare più velocemente è questa:
Bene, questa è l'emulazione. Sì, è abbastanza possibile che sia più veloce del ciclo standard. Ma probabilmente solo a spese di un tempo di inizializzazione più lento del costrutto di controllo stesso.
E quante iterazioni ci sono in questo "ciclo"?
Un po' più veloce.
Hee:)
In linea di principio, sì. L'assemblatore ha jmp. Quindi per cosa è stato progettato?
goto è un ottimo sostituto dove non ci sono eccezioni, ma avete bisogno di qualcosa come un blocco finally.
Naturalmente, anche gli if sono buoni, ma goto è probabilmente ancora più elegante.
Ma in generale, non ha senso mangiare gli spaghetti con uno stuzzicadenti se si ha una forchetta normale.
E il programmatore che prenderà il codice dopo di voi non vi darà una pacca sulla testa.