![]()  | 
	
 
  | 
		
			
  | 	
	
	
		
		|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
![]()  | 
	
	
| 
		 | 
	Опции темы | Поиск в этой теме | Опции просмотра | 
| 
		 
			 
			#16  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Я не знаю как ты тестил, но код, который я привел в примере, 1000 итераций на файле 66 852 700 байт (1 591 731 строк) выполняет мгновенно, за 0,00118835431432329 сек. 10000 итераций за 0,0126044552868083 сек. Разовый поиск за 6,84213423583157E-6 сек. Последний раз редактировалось M.A.D.M.A.N., 13.02.2015 в 22:44.  | 
| 
		 
			 
			#17  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Bargest, Нет строки разные, поиск шёл по слову. 
		
	
		
		
		
		
			
		
		
		
		
		
			M.A.D.M.A.N. Я просто взял массив array of string, который динамически расширял и заносил сортированный список. Функцию поиска просто скопипастил, единственно заменил TStringArray на array of string, т.к. у меня массив использовался, если быть точным MASS : array of array [0..2] of string (да, такой вот странный) и на функцию подавал MASS[0] . Затем поставил GetTickCount и запустил цикл поиска 10000 раз по первому слову в массиве, слову в середине массива, и последнему слову в массиве, GetTickCount снимал после циклов поиска каждого слова. После чего вывел среднее арифметическое из 3 результатов, аналогично для разных длин массива. А теперь об ошибке, - когда я передал функции массив длинной 1 700 000, он выбил Ошибку. И еще, обрати внимание, я время указывал в Миллисекундах. Опять таки, возможно, я использовал на форме, а у вас возможно в консоли. Возможно комп слабее/мощнее. Что бы было нагляднее, проведи тестирование тоже всех 4 видов... Конечно я согласен, что тупо перебор слово в первой строке найдет мгновенно, а последнее слово - чем больше массив тем дольше,.. Ясен перец Бинарный поиск в огромном массиве найдет в разы быстрее, но у меня почему-то результат обратный - наверное что-то не так сделал - не отрицаю, сам был удивлён. Последний раз редактировалось SCrat.ORS, 13.02.2015 в 23:14.  | 
| 
		 
			 
			#18  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
  | 
| 
		 
			 
			#19  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Комп 4 ядра, тестировал на форме, вместо «счетчика клещей», я использовал «перформанс каунтер». По поводу тайминга: Код: 
	10^−1 деци 10^−2 санти 10^−3 милли 10^−6 микро 10^−9 нано 10^−12 пико 10^−15 фемто 10^−18 атто 10^−21 зепто 10^−24 иокто Последний раз редактировалось M.A.D.M.A.N., 14.02.2015 в 08:57.  | 
| 
		 
			 
			#20  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Все-таки в моём понимании массив - это array а не StringList... 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	А почему в бинарном поиске у меня вылезает ошибка стека при большом количестве записей - не понимаю... другие то функции ошибки не вызывают.  | 
| 
		 
			 
			#21  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Чем вообще обусловлен выбор array? 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
| 
		 
			 
			#22  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Ну изначально вопрос встал так: 
		
	
		
		
		
		
			
		
		
		
		
		
			У меня есть какой-то файл, в котором содержится информация об каких-либо свойствах объектов, а именно - название, длина, ширина, который я загружаю в один array. Так же имеется список, скажем выставленных объектов на карту (пусть так), где записано, ИД объекта, его координаты (x,y) и название объекта, которые я загружаю в другой array, и непосредственно с этим массивом работаю. И при отрисовке объекта на карте мне надо получить его длину и ширину. И тут вызываю поиск по массиву с информацией - передаю название объекта, на выходе получаю длину и ширину (пусть в TPoint, - не суть)... поэтому и получается что использовать StringList как-то не правильно. А список выставленных объектов иногда может переваливать за несколько тысяч, а то и десятков тысяч... Идея такова. Да и по жизни я стараюсь использовать array of myTypes для запоминания свойств объектов. Когда реализовывал задачу, я подумал, что перебор по всем строкам массива будет очень медленным способом поиска и сделал кроме основного массива с информацией еще и stringList, где в том же порядке записал просто названия объектов, а далее при работе просто вызывал IndexOf и получал нужный мне индекс. Потом по этому индексу брал из массива информацию. Теперь, как я понял, я выбрал самый тормознутый способ. В любом случае Пост получился довольно интересным для меня, за что всем принявшим участие в нем - огромное спасибо. Конечно хочется развить тему дальше и найти самый продуктивный способ как поиска так и хранения свойств каких-либо объектов (частенько требуется). Последний раз редактировалось SCrat.ORS, 14.02.2015 в 14:09.  | 
| 
		 
			 
			#23  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
  | 
| 
		 
			 
			#24  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Есть множество объектов на карте. У каждого есть уникальный ID. Зачем передавать название объекта, когда можно передавать ID? Если по названию находится не сам объект, а его прототип (общий для нескольких объектов), то что мешает в массиве объектов хранить не имя, а индекс прототипа или (лучше) сразу указатель на него и не искать ничего вообще? Нужно просто нормально организовать данные. Если нужно отрисовать объект, то отрисовка должна происходить не по имени, а по индексу/указателю. Также должно быть можно через индексы/указатели от объекта добраться ко всем данным, которые могут потребоваться для отрисовки. Даже известный мне шедевр игрового убожества, наглядное пособие "как НЕ надо писать игры", и те не додумались каждые 20мс брутфорсить 10к строк, а просто посчитали от имени 4-байтовый хеш, запихнули в хеш-таблицу по первым двум байтам и положили болт на потенциальные коллизии, т.е. у них во время выполнения имен фактически нет вовсе. Не говоря уже о том, что для отрисовки не используется даже ID - он им нужен по-моему только для интегрированных скриптов. Последний раз редактировалось Bargest, 14.02.2015 в 16:42.  | 
| 
		 
			 
			#25  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Сначала загружаю информацию о "протопитах" в отдельный массив. Потом в рабочий массив загружаю информацию об объектах, тут же попутно нахожу "протопип" по названию, и подгружаю туда же нужную информацию о "прототипе". Т.Е. поиск мне необходим только при первом запуске, что бы получить всю нужную информацию. И потом в процессе работы никакго поиска не произвожу вообще.  | 
| 
		 
			 
			#26  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Цитата: 
	
 То есть просто копипастим с вики crc8/crc16/crc32, берем младшие 1-2 байта результата, используем как индекс в массиве динамических списков. Каждый N-ный элемент - список прототипов, хеш от имени которых начинается на N. Поскольку хеши стремятся к равномерному "распределению", то таблица будет заполняться равномерно, и в среднем поиск будет производиться не среди 10к строк, а среди 10к/256 или 10к/65536 строк если брать 1 или 2 байта хеша соответственно. А можно взять и 1.5 байта хеша и будет поиск среди 10к/4096, т.е. в среднем среди двух строк. И кстати, я бы сделал наоборот. Сарзу загружаю информацию об объектах, ищу для них по хеш-таблице прототип, и если не найден - загружаю прототип и добавляю в хеш-таблицу. Это позволит загружать только нужные прототипы, а не все (ведь на одной карте могут использоваться не все прототипы). Последний раз редактировалось Bargest, 14.02.2015 в 17:14.  | 
| 
		 
			 
			#27  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
  | 
| 
		 
			 
			#28  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Можно конечно и свой велосипед придумать, но есть готовые решения, считаемые легко и довольно удобно. Я обычно использую табличные варианты. Из простых есть еще известный ror13-хеш: 
		
	
		
		
		
		
			
		
		
		
		
		
			Код: 
	hash := 0; for i := 1 to length(str) do hash := ((hash shl (32-13)) or (hash shr 13)) + str[i]; При удалении в данном случае достаточно опять же найти нужный элемент и исключить из соответствующего списка. И вообще, вот. Последний раз редактировалось Bargest, 14.02.2015 в 17:37.  | 
| 
		 
			 
			#29  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Просто оставлю это здесь 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	Код: 
	//  Name  : CRC-8
//  Poly  : 0x31    x^8 + x^5 + x^4 + 1
//  Init  : 0xFF
//  Revert: false
//  XorOut: 0x00
//  Check : 0xF7 ("123456789")
function crc8(Buffer:String):byte; 
var
  i,j: Integer;
begin
Result:=$FF;
for i:=1 to Length(Buffer) do begin
  Result:=Result xor ord(buffer[i]);
  for j:=0 to 7 do begin
    if (Result and $80)<>0 then Result:=(Result shl 1) xor $31
    else Result:=Result shl 1;
    end;
  end;
end; | 
| 
		 
			 
			#30  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Bargest, спасибо за наводку. 
		
	
		
		
		
		
			
		
		
		
		
		
			Результат: 2 000 000 Строк, 100 000 циклов поиска: Среднее время поиска 0,078 мсек. Результат Бинарного поиска от M.A.D.M.A.N. (который мне не удалось сделать, поэтому результат его) 12,6 мсек. (0,0126044552868083 сек). Это конечно несколько разные подходы к организации массивов и поиска, но ради интереса. Так что да,.. хранить нужно с хешем. M.A.D.M.A.N. Твой результат в мсек. примерно тоже самое что у меня и показывает. Так что все более менее одинаково и твои Мгновенно - это и есть 11 мсек. Вероятно Бинарный поиск дает свои плоды если количество слов более 10млн, т.к. до 2 млн, он по вычислениям почти совпадает с Простым перебором. Вот такое вот исследование. Вот как реализовал: Код: 
	
...
Type TMyArray = Packed Record
SomeName:String;
end;
Type
MyArray = array [$00..$FF] of Array of TMyArray;
...
function crc8(Buffer:String):byte;
var
  i,j: Integer;
begin
Result:=$FF;
for i:=1 to Length(Buffer) do begin
  Result:=Result xor ord(buffer[i]);
  for j:=0 to 7 do begin
    if (Result and $80)<>0 then Result:=(Result shl 1) xor $31
    else Result:=Result shl 1;
    end;
  end;
end;
function FindM(const AText: string; const AValues: array of TMyArray): Integer;
var
  I: Integer;
begin
  Result := -1;
  for I := Low(AValues) to High(AValues) do
    if AText=AValues[i].SomeName then
    begin
      Result := I;
      Break;
    end;
end;
Function Find(S:String; M: MyArray):TPoint;
Var
NDX:Integer;
Begin
NDX:=CRC8(s);
Result.X:=NDX;
Result.Y:=FindM(s,M[NDX]);
End;
...
procedure TForm1.Button1Click(Sender: TObject);
Var
I:TPoint;
N:String;
begin
I:=Find('СТРОКА ПОИСКА', MItemInformation); //MItemInformation - Это массив в котором ищем
If i.Y>-1 then N:=MItemInformation[I.X,I.Y].SomeName;
end;
Последний раз редактировалось SCrat.ORS, 14.02.2015 в 19:37.  |