Что нового

[Массивы] _ArrayDelete очень медленный

peter911

Новичок
Сообщения
18
Репутация
0
Например удаление 10 тыс. элементов очень заметно. Проверил, другое не может замедлять работу.
Код:
Func toPoint(ByRef $Arr, $e=1)
   Local $i=0, $j=0
   While $i < UBound($Arr)
	  $j = $i+1
	  While $j < UBound($Arr)
		 If (Abs($Arr[$j][0]-$Arr[$i][0]) <= $e And Abs($Arr[$j][1]-$Arr[$i][1]) <= $e) Then
			_ArrayDelete($Arr, $i)
			$i -= 1
			ExitLoop
		 Else
			$j += 1
		 EndIf
	  WEnd
	  $i += 1
   WEnd
EndFunc

У меня цвет в изображении быстрей намного ищет, чем элементы удаляет(которых гораздо меньше)
И это не из-за цикла.


Добавлено:
Сообщение автоматически объединено:

Код:
; #FUNCTION# ====================================================================================================================
; Name...........: _ArrayDelete
; Description ...: Deletes the specified element from the given array.
; Syntax.........: _ArrayDelete(ByRef $avArray, $iElement)
; Parameters ....: $avArray  - Array to modify
;                  $iElement - Element to delete
; Return values .: Success - New size of the array
;                  Failure - 0, sets @error to:
;                  |1 - $avArray is not an array
;                  |3 - $avArray has too many dimensions (only up to 2D supported)
;                  |(2 - Deprecated error code)
; Author ........: Cephas <cephas at clergy dot net>
; Modified.......: Jos van der Zande <jdeb at autoitscript dot com> - array passed ByRef, Ultima - 2D arrays supported, reworked function (no longer needs temporary array; faster when deleting from end)
; Remarks .......: If the array has one element left (or one row for 2D arrays), it will be set to "" after _ArrayDelete() is used on it.
;+
;                  If the $ilement is greater than the array size then the last element is destroyed.
; Related .......: _ArrayAdd, _ArrayInsert, _ArrayPop, _ArrayPush
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _ArrayDelete(ByRef $avArray, $iElement)
	If Not IsArray($avArray) Then Return SetError(1, 0, 0)

	Local $iUBound = UBound($avArray, 1) - 1

	If Not $iUBound Then
		$avArray = ""
		Return 0
	EndIf

	; Bounds checking
	If $iElement < 0 Then $iElement = 0
	If $iElement > $iUBound Then $iElement = $iUBound

	; Move items after $iElement up by 1
	Switch UBound($avArray, 0)
		Case 1
			For $i = $iElement To $iUBound - 1
				$avArray[$i] = $avArray[$i + 1]
			Next
			ReDim $avArray[$iUBound]
		Case 2
			Local $iSubMax = UBound($avArray, 2) - 1
			For $i = $iElement To $iUBound - 1
				For $j = 0 To $iSubMax
					$avArray[$i][$j] = $avArray[$i + 1][$j]
				Next
			Next
			ReDim $avArray[$iUBound][$iSubMax + 1]
		Case Else
			Return SetError(3, 0, 0)
	EndSwitch

	Return $iUBound
EndFunc   ;==>_ArrayDelete



Добавлено:
Сообщение автоматически объединено:

Я полностью изменил алгоритм функции, но вроде быстрей не стало
Код:
#include <Array.au3>
Dim $A[4][2] = [[0, 1], [1, 2], [5, 6], [4, 5]]
_ArrayDisplay(toPoint($A))
Func toPoint(ByRef $Arr, $e=1)
   Local $k=0
   Dim $Res[UBound($Arr)][2]
   For $i=0 To UBound($Arr)-1
	  $n=$i
	  For $j=$i+1 To UBound($Arr)-1
		 If Not((Abs($Arr[$j][0]-$Arr[$n][0]) > $e Or Abs($Arr[$j][1]-$Arr[$n][1]) > $e)) Then $n = $j
	  Next
	  If $n == $i Then
		 $Res[$k][0] = $Arr[$n][0]
		 $Res[$k][1] = $Arr[$n][1]
		 $k += 1
	  EndIf
   Next
   ReDim $Res[$k][2]
   Return $Res
EndFunc
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
peter911, вот грубо навскидку. без проверок

Код:
#include <Array.au3>
Dim $array[10000]
$timer = TimerInit()
For $i = 0 To 10000
	If $i = 9999 Then ExitLoop
	ReDim $array[UBound($array) - 1]
Next
ConsoleWrite(TimerDiff($timer)&@CRLF)
_ArrayDisplay($array)

то есть сам изменяй размерность массива используя
Код:
ReDim

тогда будет быстрее.
 
Автор
peter911

peter911

Новичок
Сообщения
18
Репутация
0
Я проверял ReDim сотню тысяч раз дает задержку. Поэтому делаю вызов в конце один раз.

ReDim $array[UBound($array) - 1]
Мне нужно не последний элемент удалить.
 

avmaksimov

Новичок
Сообщения
46
Репутация
4
Если нужно много удалить, быстрее будет вручную перекинуть: создайте новый массив и перекиньте туда только то, что нужно.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Вместо удаления вставляй -1. Потом после 100 операций удалишь за один проход. А так все функции медленные, если алгоритм неправильно делать.
 
Автор
peter911

peter911

Новичок
Сообщения
18
Репутация
0
Re: [Массивы] _ArrayDelete очень медленныйAZJIO

AZJIO сделай правильно алгоритм


Добавлено:
Сообщение автоматически объединено:

Не понимаю почему перенесли тему в другой разделъ
 
Верх