Что нового

Быстрая генерация "мусора" в файл

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Здравствуйте, помогите пожалуйста написать генератор "Мусора" в файл.
Для прояснения почему нужно именно быстро скажу что - генерация должна зависеть от размера указанного в функцию.
Я уж сам капельку набросал очертание, но работает функция весьма долго учитывая то что генерировать следует не маленькие по объему данные:
Код:
FileWrite(@DesktopDir&"\1.txt",__Pake(40))
MsgBox(64,"","End")
Func __Pake($SizeValue)
	Local $s_Temp
	For $i=0 To $SizeValue*1024*1024 Step 1; Размер требуется в мегабайтах
		$s_Temp&=Chr(Random(65,122))
	Next
	Return $s_Temp
EndFunc

OffTopic:
Хотел написать библиотеку на PB, но там все время какая нибудь ошибка
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
MnM,
Код:
;...
Chr(Random(65,122))
;...
А эти данные нужны? Или достаточно создать пустой файл заданного размера?
 

MaximK

Знающий
Сообщения
33
Репутация
5
40 mb 1 минута
Код:
Opt('TrayIconDebug',1)
_CreateGarbageTXTFile(@DesktopDir&"\1.txt",40)

;$Path - путь к файлу
;$Size - размер в мегабайтах
Func _CreateGarbageTXTFile($Path,$Size)
	$hFile=FileOpen($Path,1)
	For $i=0 To $Size*1024
		Local $buff=''
		For $ii =0 To 1024
			$buff&=Chr(Random(65,122))
		Next
		FileWrite($hFile,$buff)
	Next
	FileClose($hFile)
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
MaximK [?]
Так быстрее.
Код:
#include <WinAPI.au3>

Local $iSizeMgb = 50, $iMgb = 1024 * 1024, $iStep = $iMgb / 8, $tDouble = DllStructCreate('double[' & $iStep & ']'), _
		$pDouble = DllStructGetPtr($tDouble), $hFile, $iWrite, $iTime = TimerInit()

$hFile = _WinAPI_CreateFile(@ScriptDir & '\Txt.txt', 1)
For $i = 1 To $iSizeMgb
	For $j = 1 To $iStep
		DllStructSetData($tDouble, 1, Random(), $j)
	Next
	_WinAPI_WriteFile($hFile, $pDouble, $iMgb, $iWrite)
Next
_WinAPI_CloseHandle($hFile)
ConsoleWrite(StringFormat('%.2f sec', TimerDiff($iTime) / 1000) & @LF)
 

sims

Осваивающий
Сообщения
184
Репутация
24
OffTopic:
MnM [?]
Хотел написать библиотеку на PB, но там все время какая нибудь ошибка
Конечно если компилировать автоит код в PB, будут ошибки. ;) 8)
Код библиотеки.
Код:
#LenBlock = 1024*1024

ProcedureDLL Pake(FileName.s, SizeMB)
  If SizeMB>0
    If CreateFile(0, FileName)
      
      Dim Buff.a(#LenBlock)
      For i=1 To SizeMB
        RandomData(@Buff(), #LenBlock)
        If WriteData(0, @Buff(), #LenBlock) <> #LenBlock
          Break ; Ошибка.
        EndIf
      Next
      
      CloseFile(0)
    EndIf
  EndIf
EndProcedure
Как создать dll из кода, писал ранее.
Вызов функции из dll.
Код:
$File="Test.bin"
$Size=100
DllCall('Pake.dll', 'int', 'Pake', 'str', $File, 'int', $Size)
Скорость генерации составила примерно 70 МБ/с. Но похоже что это из-за ограничения винта. На более скоростном винте и без фрагментации, возможно будет в несколько раз большая скорость работы.
 

ivsatel

Продвинутый
Сообщения
319
Репутация
84
Мой вариант:
Код:
Local $s_Temp = '1'

;	20 = # Размер 2 МБ	#	>Exit code: 0    Time: 1.293	#	TimerDiff	45.9560995573017
;	21 = # Размер 4МБ	#	>Exit code: 0    Time: 1.989	#	TimerDiff	546.922153421304
;	22 = # Размер 8МБ	#	>Exit code: 0    Time: 2.717	#	TimerDiff	1308.09981281405
;	23 = # Размер 16МБ	#	>Exit code: 0    Time: 4.361	#	TimerDiff	2871.39501288238
;	24 = # Размер 32МБ	#	>Exit code: 0    Time: 7.342	#	TimerDiff	6573.16204893881
;	25 = # Размер 64МБ	#	>Exit code: 0    Time: 14.788	#	TimerDiff	10888.6343831405
;	26 = # Размер 128МБ	#	>Exit code: 0    Time: 48.577	#	TimerDiff	30018.4178154048
;	27 = # Error allocating memory.

For $i = 0 To 27
	$s_Temp &= $s_Temp
Next

FileWrite(@ScriptDir&'\1simbol.txt', $s_Temp)
 
Автор
MnM

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Всем огромное спасибо, честно признаться очень был удивлен вашими примерами в компактности, еще раз спасибо :smile:
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
sims [?]
Скорость генерации составила примерно 70 МБ/с. Но похоже что это из-за ограничения винта. На более скоростном винте и без фрагментации, возможно будет в несколько раз большая скорость работы.
Набросал следующий вариант, на стареньком ноуте показывает результат всего лишь в два раза хуже. Так что не такой уж и отрыв у ваших компилируемых ЯП, уверен на машинах с более большим объемом оперативы скорость как и ваша упрется в ЖД.
Главное в AutoIt - найти верный подход. Это иногда избавляет от надобности компилируемых языков в решении задачи.

1gb - 32sec
2gb - 61sec

Код:
#Include <WinAPI.au3>

$hTimer = TimerInit()
If Not _CreateFile( "sample.bin", 1 * 1024 * 1024 * 1024, 1024 * 1024 ) Then _
   Exit MsgBox( 16, "error", "err=" & @Error )
   
MsgBox( 64, '', "TimerDiff=" & TimerDiff( $hTimer ) )

Func _CreateFile( $sName, $iSize, $iBlockSize )
   Local $tStruct, $pStruct, $hFile, $Idx, $iTo, $iBytes, $iErr = 0
   ; ---
   If $iBlockSize > $iSize Then _
	  Return SetError( -1, 0, False )
   
   If Mod( $iSize, $iBlockSize ) Then _
	  Return SetError( -2, 0, False )
   ; ---
   $tStruct = DllStructCreate( "byte[" & $iBlockSize & "]" )
	  $pStruct = DllStructGetPtr( $tStruct )
	  DllStructSetData( $tStruct, 1, Binary( 0x00 ) )

   $iTo = $iSize / $iBlockSize
   $hFile = _WinAPI_CreateFile( $sName, 1 )
   For $Idx = 1 To $iTo Step 1
	  If Not _WinAPI_WriteFile( $hFile, $pStruct, $iBlockSize, $iBytes ) Or $iBytes <> $iBlockSize Then
		 $iErr = @Error
		 ExitLoop
	  EndIf
	  ConsoleWrite( $Idx & "/" & $iTo & @CRLF )
   Next
   _WinAPI_CloseHandle( $hFile )
   ; ---
   If $iErr Then _
	  Return SetError( $iErr, 0, False )
	  
   Return True
EndFunc
 

sims

Осваивающий
Сообщения
184
Репутация
24
firex [?]
Набросал следующий вариант, на стареньком ноуте показывает результат всего лишь в два раза хуже.
Только вот соответствует ли код условиям задачи? Генерирует ли он случайные числа? По факту, в файл используя WinAPI пишется содержимое структуры и при этом от Автоита большого быстродействия не требуется, ведь все задачи возложены на WinAPI и все равно он не справляется по времени даже с такой простой задачей.

Для справки, если в этом коде убрать запись в файл, то скорость выполнения составит 1 ГБ в секунду. Это время тратится в основном на генерацию случайных чисел, т. е. за секунду генерируется миллиард случайных чисел! :shok: На автоите можно хотя бы миллион в секунду получить? :scratch: Но все равно. :IL_AutoIt_1: :beer:

Главное в AutoIt - найти верный подход. Это иногда избавляет от надобности компилируемых языков в решении задачи.
Толку от этого решения если оно не соответствует условию? Нет генерации случайных чисел, а без этого, в файле не будет "мусора".
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
sims [?]
Толку от этого решения если оно не соответствует условию? Нет генерации случайных чисел, а без этого, в файле не будет "мусора".
Да банально слить системную память и в результате тот же мусор, зачем его генерировать? :smile:
 

sims

Осваивающий
Сообщения
184
Репутация
24
firex [?]
Да банально слить системную память
Ну попробуйте. :rofl:
Потом расскажите куда "послала" система при доступе к физической памяти. А если все таки получится, расскажите с какой скоростью сливали? :rofl:

результате тот же мусор, зачем его генерировать
Нет не тот же. Далеко не вся память заполнена "мусором" и не все данные являются таковым.
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
sims, firex

Не спорьте :smile:, PureBasic без сомнений быстрее чем AutoIt, но код нужен на AutoIt, и я соглашусь с sims, firex твой код не выполняет поставленной задачи..

И не много от меня, код правда не на AutoIt но делает почти тоже самое что и код firex, вот только он создаёт файл размером 8 Гб заполненный нулями за 15 млс. *click*
 

sims

Осваивающий
Сообщения
184
Репутация
24
Viktor1703 [?]
но код нужен на AutoIt
Была предложена библиотека для автоита. По моему хороший компромисс, особенно учитывая что "Автор темы" писал о том же.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Viktor1703

sims [?]
Не буду спорить на счет организации этого дела AutoIt, но это не такая уж и проблема. :smile:

Viktor1703
Понятное дело. Однако скорость в моем примере можно увеличить в несколько раз на более мощной машине, в этом ноуте всего 756mb, из которых сейчас ~200 свободно. :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Если нужно чисто на AutoIt, то можно написать следующим образом:

Код:
#Include <WinAPIEx.au3>

_Pake(@ScriptDir & '\Test.txt', 10)

Func _Pake($sFile, $iSizeMB)

	Static $tBuff, $pBuff = 0

	Local $hFile, $tData, $pData, $Bytes, $Error = 0

	If Not $pBuff Then
		$tBuff = DllStructCreate('byte[1048576]')
		$pBuff = DllStructGetPtr($tBuff)
		$tData = DllStructCreate('byte[1024]')
		$pData = DllStructGetPtr($tData)
		For $i = 1 To 1024
			DllStructSetData($tData, 1, Random(65, 122, 1), $i)
		Next
		For $i = 1 To 1024
			_WinAPI_MoveMemory($pBuff + ($i - 1) * 1024, $pData, 1024)
		Next
	EndIf
	$hFile = _WinAPI_CreateFile($sFile, 1, 4)
	If Not $hFile Then
		Return SetError(1, 0, 0)
	EndIf
	For $i = 1 To $iSizeMB
		If (Not _WinAPI_WriteFile($hFile, $pBuff, 1048576, $Bytes)) Or ($Bytes <> 1048576) Then
			$Error = 1
			ExitLoop
		EndIf
	Next
	_WinAPI_CloseHandle($hFile)
	If $Error Then
		Return SetError(2, _WinAPI_DeleteFile($sFile), 0)
	EndIf
	Return 1
EndFunc   ;==>_Pake


Думаю, можно допустить, что множество повторяющихся блоков мусора по 1 КБ все равно останется мусором. :smile:
 
Верх