Что нового

[Массивы] Ускорить слив данных с двух массивов

korvindeson

Новичок
Сообщения
19
Репутация
0
Добрый день. Есть такой вопрос, не приходит в голову сам подход, не могу даже погуглить. Суть вещей. Есть 2 массива (15-30 тысяч каждый).
В них данные типа:
1-й массив ----> номер-дата
2-й массив ----> _номер-признак-признак2

Что делаю? Перебираю все элементы первого массива, ищу номер во втором, если нахожу, сливаю в файл.

Код:
for $i=0 To $TXT-1
   $s = StringSplit($aOtchet[$i],"-")
   for $j=0 To $DataBase-1
	  if StringInStr($aOtchetDB[$j],$s[1]) <> 0 Then
		 $s2 = StringSplit($aOtchetDB[$j],"-")
		 FileWriteLine ($Otch,"<tr><td>" & $s[1] & "</td><td>" & $s[2] & "</td><td>" & $s2[2] & "</td><td>" & $s2[3] & "</td></tr>")
		 ExitLoop
 	  EndIf
   Next
Next

Но эта конструкция работает просто таки годами на двух массивах по 20-30 тысяч. Как по человечески сделать подскажите. Отсортировать или в базу данных записать или ещё что?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
korvindeson [?]
В них данные типа:
приведи пример каждого массива. первые 3 элемента например. а то так непонятно, что в массивах. мне по крайней мере.
 
Автор
K

korvindeson

Новичок
Сообщения
19
Репутация
0
Без проблем:
1-й массив 4 элемента:
754702-08.04.2015 17:26:39
754796-08.04.2015 17:26:39
754807-08.04.2015 17:26:39
754815-08.04.2015 17:26:40

2-й массив 4 элемента:
_754102-130-0451298
_759216-130-0451298
_754815-129-0451298
_750017-128-0451298

Соответственно, выделяю к примеру "754702", ищу во втором массиве, нахожу. Добавляю данные через тире. Запустил сейчас 15к и 26к массивы. Уже час пашет, зараза. Не пойму почему так долго.
Может массивы в текстовики загнать и другим языком быстро собрать? Не посоветуете куда глядеть если так?

_____________
Нашёл небольшое исправление, так работает быстрее, но не радикально. Сравниваем не при помощи StringInStr, а меняем "_" на ничего, сравниваем 2 числа.
Код:
for $i=0 To $TXT-1
   $s = StringSplit($aOtchetTXT[$i],"-")
   if $s[0] >= 2 Then
	  for $j=0 To $DataBase-1
		 $s2 = StringSplit($aOtchetDB[$j],"-")
		 StringReplace($s2[1],"_","")
		 if $s2[1] = $s[1] Then
			FileWriteLine ($Otch,"<tr><td>" & $s[1] & "</td><td>" & $s[2] & "</td><td>" & $s2[2] & "</td><td>" & $s2[3] & "</td></tr>")
			ExitLoop
		 EndIf
	  Next
   EndIf
Next
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
более оптимальным будет загнать второй массив в словарь. в AutoIt ЕМНИП нет нативной поддержки словарей. поищи по форуму Scripting.Dictionary. этот словарь будет опорным. потом проходишь по элементам первого массива и ищешь ключ в опорном словаре. это намного быстрее.
 
Автор
K

korvindeson

Новичок
Сообщения
19
Репутация
0
Огонь :laugh: Вместо часа секунд 15, спасибо огромное!

Код:
;гоним в словарь
for $j=0 To $DataBase-1
   $s = StringSplit($aOtchetDB[$j],"-")
    $aOtchetSL.Add($s[1], $s[2] & "-" & $s[3])
Next

;пишем файл
for $i=0 To $TXT-1
   $s = StringSplit($aOtchetTXT[$i],"-")
   if $s[0] >= 2 Then
	  $vValue = $aOtchetSL.Item($s[1])
	  FileWriteLine ($Otch,"<tr><td>" & $s[1] & "</td><td>" & $s[2] & "</td><td>" & $vValue  & "</td></tr>")
   EndIf
Next
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Не нужно забывать, что операции с диском являются самыми медленными. Поэтому по возможности нужно обращаться к диску как можно реже. В данном примере FileWriteLine() совершенно не оправдана и будет люто тормозить выполнение скрипта.

Код:
$sData = ""

For $i = 0 To $TXT - 1
	$s = StringSplit($aOtchetTXT[$i], "-")
	If $s[0] >= 2 Then
		For $j = 0 To $DataBase - 1
			$s2 = StringSplit($aOtchetDB[$j], "-")
			If $s[1] = '_' & $s2[1] Then
				$sData &= "<tr><td>" & $s[1] & "</td><td>" & $s[2] & "</td><td>" & $s2[2] & "</td><td>" & $s2[3] & "</td></tr>" & @CRLF
				ExitLoop
			EndIf
		Next
	EndIf
Next

FileWrite($Otch, $sData)


Второй момен, позволяющий повысить производительность, это использовать строку вместо одного из массивов, а поиск производить с помощью StringInStr(). Саму строку можно задать, например, так:

Код:
$sOtchetDB = "_754102-130-0451298|_759216-130-0451298|_754815-129-0451298|..."
 
Автор
K

korvindeson

Новичок
Сообщения
19
Репутация
0
Yashied, за операцию с диском думал, прятал строку под коммент, результат микроскопический был. С этой задачей словарь справился, но на будущее как эффективнее будет делать через словарь или по методу загнать массив в стринг и StringInStr()?
 
Верх