Перейти к содержанию

Помогите написать скоростной велосипед на C/C++


Nobi

Рекомендуемые сообщения

Опубликовано (изменено)

Знатоки, помогите вот этот мой велосипед переписать на C/C++ и чтобы максимально быстро работал. Ну там буфер какой прикрутить.

 


Global $x = 0, $y = 0, $hFile1 = 0, $hFile2 = 0
$hFile1 = FileOpen($CmdLine[2], $FO_BINARY)
$hFile2 = FileOpen($CmdLine[3], $FO_BINARY)
For $i = 1 To $CmdLine[1]
	If FileRead($hFile1, 1) == FileRead($hFile2, 1) Then
		$x += 1
	Else
		$y += 1
	EndIf
Next
FileClose($hFile1)
FileClose($hFile2)
ConsoleWrite($x & @CRLF & $y & @CRLF)



Exit

 

На C оно както так будет, но я сомневаюсь что это быстрый и правильный вариант

 

#include <stdio.h>

int main(int argc, char *argv[])
{
	int i = 0, x = 0, y = 0, z = 0;
	FILE *fp1, *fp2;
	sscanf(argv[1], "%d", &x);
	fp1 = fopen(argv[2],  "rb");
	fp2 = fopen(argv[3],  "rb");
	for (i = 0; i < x; i++)
	{
		if (fgetc(fp1) == fgetc(fp2))
		{
			y++;
		}
		else
		{
			z++;
		}
	}
	fclose(fp1);
	fclose(fp2);
	printf("%d\n%d", y, z);
	return 0;
}

 

Изменено пользователем Nobi
Опубликовано (изменено)

Получил вариант работающий в 20 раз быстрее, но неплохобы еще ускорить.

 

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

int main(int argc, char *argv[])
{
	FILE *pFile1, *pFile2;
	if (fopen_s(&pFile1, argv[1], "rb") || fopen_s(&pFile2, argv[2], "rb") || _fseeki64(pFile1, 0, SEEK_END) || _fseeki64(pFile2, 0, SEEK_END))
	{
		return 1;
	}
	__int64 i64FileSize1 = _ftelli64(pFile1), i64FileSize2 = _ftelli64(pFile2), i64FileSize = (i64FileSize1 < i64FileSize2 ? i64FileSize1 : i64FileSize2), i64Matches = 0, i64Mismatches = 0;
	if (i64FileSize1 < 0 || i64FileSize2 < 0 || i64FileSize < 0 || _fseeki64(pFile1, 0, SEEK_SET) || _fseeki64(pFile2, 0, SEEK_SET))
	{
		return 1;
	}
	__int8 *aFile1 = malloc(i64FileSize), *aFile2 = malloc(i64FileSize);
	if (aFile1 == NULL || aFile2 == NULL || fread_s(aFile1, i64FileSize, 1, i64FileSize, pFile1) != i64FileSize || fread_s(aFile2, i64FileSize, 1, i64FileSize, pFile2) != i64FileSize || ferror(pFile1) || ferror(pFile2) || feof(pFile1) || feof(pFile2))
	{
		return 1;
	}
	fclose(pFile1);
	fclose(pFile2);
	for (__int64 i = 0; i != i64FileSize; ++i)
	{
		if (aFile1[i] == aFile2[i])
		{
			i64Matches++;
		}
		else
		{
			i64Mismatches++;
		}
	}
	printf_s("%I64d\n%I64d\n%I64d", i64Matches, i64Mismatches, (i64FileSize1 < i64FileSize2 ? i64FileSize2 - i64FileSize1 : i64FileSize1 - i64FileSize2));
	return 0;
}

 

Изменено пользователем Nobi
Опубликовано

Понятно, что тема уже может не актуальна. Но если кто будет читать.

1. Не указана точная задача, для чего надо. (да по коду видно,что два файла сравниваются, но для чего?) для сравнения двух файлов, есть утилиты.

2. В последнем варианте, всё грузится в память и по байтово сравнивается, если сравнивать данные как 64 битные числа (процесс сравнение в 8 раз ускорится), или задействовать SIMD инструкции, то можно в разы увеличить скорость.

3. Если файлы окажутся большие, не хватит оперативки, то тоже возникнут проблемы...

 

Но вот какой момент, в этом деле главное загрузка с диска. И вот если задача стоит сотни файлов сравнивать между собой, то подход надо полностью менять... Тупо делаем для каждого файла хешзначение и сравниваем их между собой. 

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...