Что нового

[Данные, строки] Удалить из файла все повторения

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
CreatoR сказал(а):
Garrett [?]
Что-то висит код
Что значит висит, он обрабатывает строки ;D - какой размер файла?
Мда... :shok:
Time: 786.598 = 13 мин 11 сек
Файл который предоставил ZanMax 3,8 Мб
Скрипт нашёл одну строку :smile:
P.S. Съедает 50% ресурсов :(
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
CreatoR [?]
Быстрее этого думаю уже не сделать на AutoIt:

Замена :
Код:
 StringInStr  на StringRegExp
намного ускорит процесс (я сравнивал) , хотя этого все равно недостаточно
 
Автор
Z

ZanMax

Тестер
Сообщения
120
Репутация
5
Может екселем все это делать ?
Как думаете ? 13 минут это очень много.
таких файлов за 30 - 40 минут человеку нужно будет обработать 5 штук :wacko:
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
madmasles [?]
Получается, что нет
зависит от кол-ва операция в движке PCRE. потому как один регвыр на самом деле может свестись ко множественным текстовым операциям. и наоборот, то что будет делать построковое сравнение очень большой строки в нескольких сотнях/тысячах циклов регвыр проделает за один, к примеру. поэтому зависит от контекста. а вообще, более чем уверен что PCRE шустрый инструмент
 
Автор
Z

ZanMax

Тестер
Сообщения
120
Репутация
5
:shok: Выгрузил сегоодня данные а их болие : 5 000 000
Думаю на этом всем спасибо.
Буду думать как в базе удалять дубликаты.
:IL_AutoIt_1:
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
CreatoR
У меня получается, что _FileDeleteDuplicateLines медленнее где-то процентов на 15-20, чем примеры с Assign() и Eval()

Я взял текст из этого сообщения http://autoit-script.ru/index.php?topic=1439.msg10335#msg10335 и записал его в файл 100 000 раз (т.е. около 2 млн строк)

Следующий код:
Код:
#include <File.au3>
#include <Array.au3>
$sFileResult=@ScriptDir & '\2.txt' ; путь до файла c повторяющимися линиями

Dim $aList
_FileReadToArray($sFileResult,$aList)
 
$sText = ''
 
For $i = 1 To $aList[0]
    Assign($aList[$i] & '/\', Eval($aList[$i] & '/\') + 1)
    If Eval($aList[$i] & '/\') = 1 Then $sText &= $aList[$i] & @CRLF    
Next
	
$aList=StringSplit(StringTrimRight($sText, 2), @LF)
_ArrayDelete($aList,0)

$hFile = FileOpen(@ScriptDir & '\3.txt', 2) ; путь до результирующего файла
_FileWriteFromArray($hFile, $aList)
FileClose($hFile)

обрабатывает такой файл на моем компе примерно за 21.5 сек, а _FileDeleteDuplicateLines - 24.5 сек.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
WSWR [?]
обрабатывает такой файл на моем компе примерно за 21.5 сек, а _FileDeleteDuplicateLines - 24.5 сек.
Разница то в несколько секунд (я полагаю что использовался $iUseDict = 1), а вариант с Assign потребляет немало ресурсов памяти (это получается что на каждую строку создаётся переменная).
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
WSWR
Ваш код ещё можно оптимизировать, используя IsDeclared вместо Eval. И самое главное перед началом обработки заменить символ "[" на какой нибуть управляющий, потому что Assign не создаст переменную с этим символом, а если замена была успешна то в результирующем тексте восстановить символ "[".

Примерно так
Код:
Func _StringUnique(ByRef $sString, $spr = @CRLF)
	Local $Count = 0
	If $spr<>'[' Then
		$sString = StringReplace($sString, '[', Chr(1)) ; Символ "[" создаёт проблему, поэтому временно подменяем его непечатным символом
		$Count = @extended
	EndIf
	Local $a = StringSplit($sString, $spr, 1), $i
	Assign('/', '', 1) ; создаёт переменную, чтобы пустые строки уже являлись дубликатами и исключались из результата
	$sString = ''

	For $i = 1 To $a[0]
		If Not IsDeclared($a[$i] & '/') Then
			$sString &= $a[$i] & $spr
			Assign($a[$i] & '/', '', 1)
		EndIf
	Next
	$sString = StringTrimRight($sString, StringLen($spr))
	If $Count Then $sString = StringReplace($sString, Chr(1), '[')
EndFunc   ;==>_StringUnique
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
OffTopic:
AZJIO [?]
заменить символ "[" на какой нибуть управляющий, потому что Assign не создаст переменную с этим символом
Неплохо было бы в справке это уточнить, т.к «Не может быть элементом массива» как то смутно, ведь символ «]» можно использовать.


если замена была успешна то в результирующем тексте восстановить символ "["
Может лучше конвертировать строку в бинарный вид, чтобы избежать этой замены?
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
CreatoR [?]
Может лучше конвертировать строку в бинарный вид, чтобы избежать этой замены?
Строка увеличится вдвое и имена всех создаваемых переменных, не уверен в прибавке скорости.
Меня, кстати, волнует ограничение длинны переменной из создаваемой строки, ведь есть же предел, возможно это станет ограничением в использовании, но по крайней мере для списков путей файлов возможно предел и не будет превышен. А у объекта "Scripting.Dictionary" являющимся обычным массивом думаю нет ограничения.
 
Верх