Acelere la enumeración de archivos NTFS (usando FSCTL_ENUM_USN_DATA y NTFS MFT / USN journal)

Estoy enumerando los archivos de una partición del disco duro NTFS, mirando el diario NTFS MFT / USN con:

HANDLE hDrive = CreateFile(szVolumePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
DWORD cb = 0;

MFT_ENUM_DATA med = { 0 };
med.StartFileReferenceNumber = 0;
med.LowUsn = 0;
med.HighUsn = MAXLONGLONG;      // no change in perf if I use med.HighUsn = ujd.NextUsn; where "USN_JOURNAL_DATA ujd" is loaded before

unsigned char pData[sizeof(DWORDLONG) + 0x10000] = { 0 }; // 64 kB

while (DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL))
{
        med.StartFileReferenceNumber = *((DWORDLONG*) pData);    // pData contains FRN for next FSCTL_ENUM_USN_DATA

       // here normaly we should do: PUSN_RECORD pRecord = (PUSN_RECORD) (pData + sizeof(DWORDLONG)); 
       // and a second loop to extract the actual filenames
       // but I removed this because the real performance bottleneck
       // is DeviceIoControl(m_hDrive, FSCTL_ENUM_USN_DATA, ...)
}

Funciona, es mucho más rápido de lo habitual.FindFirstFile técnicas de enumeración. Pero yo veoaún no es óptimo:

En mis 700k archivosC:\, tarda 21 segundos (Esta medida debe realizarse después del reinicio; de lo contrario, será incorrecta debido al almacenamiento en caché).

He visto otro software de indexación (no Everything, otro) capaz de indexarC:\ en <5 segundos (medido después del inicio de Windows), sin leer una base de datos precalculada en un archivo .db (¡u otros trucos similares que podrían acelerar las cosas!). Este software no usaFSCTL_ENUM_USN_DATA, pero el análisis NTFS de bajo nivel en su lugar.

Lo que he tratado de mejorar el rendimiento.:

Abrir archivo con otra bandera, comoFILE_FLAG_SEQUENTIAL_SCAN, FILE_FLAG_RANDOM_ACCESSoFILE_FLAG_NO_BUFFERING: mismo resultado: 21 segundos para leer

Mirando aEstime el número de registros USN en el volumen NTFS, ¿Por qué la enumeración de archivos con DeviceIoControl es más rápida en VB.NET que en C ++? Los he estudiado en profundidad, pero no proporciona una respuesta a esta pregunta real.

Pruebe otro compilador: MinGW64 en lugar de VC ++ Express 2013: el mismo resultado de rendimiento, sin diferencia

En VC ++, ya he cambiado aRelease en lugar deDebug: ¿hay otras propiedades / opciones del proyecto que puedan acelerar el programa?

Pregunta:

¿Es posible mejorar el rendimiento?DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, ...)?

¿o es la única forma de mejorar el rendimiento para realizar un análisis manual de bajo nivel de NTFS?

Nota: Según las pruebas, el tamaño total a leer durante estosDeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, ...) para mis archivos de 700k essolamente 84MB. 21 segundos para leer 84 MB son solo 4 MB / seg (¡y tengo un SSD!). Probablemente haya margen para mejorar el rendimiento, ¿no le parece?

Respuestas a la pregunta(0)

Su respuesta a la pregunta