![]()  | 
	
 
  | 
		
			
  | 	
	
	
		
		|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
![]()  | 
	
	
| 
		 | 
	Опции темы | Поиск в этой теме | Опции просмотра | 
| 
		 
			 
			#1  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 По ходу написание программы. Встала задача в скорости работы программы и возник вопрос. 
		
	
		
		
		
		
		
		
			А какой тип данных быстрее проходит сравнение ? Инфы об этом я не нашел. Поэтому решил сам подсчитать. Код: 
	If a = b Then Вот сравнительная диаграмма количества проведённых операций сравнения разных типов данных. ![]() ![]() ![]() Последний раз редактировалось seeman_tm, 28.11.2013 в 20:06.  | 
| 
		 
			 
			#2  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 С чего бы это строка "9797979797979797" сравнивается быстрее строки "aaaaaaaa"? И число 9797979797979797 никак не влезет в тип Integer - что-то тут напутано.  | 
| 
		 
			 
			#3  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Сравнивается a и b. 
		
	
		
		
		
		
		
		
			Даже сравнивнение a и a Код: 
	If a=a then По сути не важно значение а и б, главное чтоб соответствовали одному и тому же типу. То есть, а и b пусть относятся к какому нибудь одному типу, и не важно какие у низ значения, результат практически одинаковый всегда. А строка "9797979797979797" сравнивается быстрее строки "aaaaaaaa" по тому что там тип данных другой. String и ShortString Почитай в чём у них отличия. Если надо, могу исходничёк кинуть. Последний раз редактировалось seeman_tm, 28.11.2013 в 18:50.  | 
| 
		 
			 
			#4  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Интересно было бы так же увидеть сравнения различных типов - int и int64, string и shortstring, string и PChar, ну и так далее. Варианты integer & float тоже были бы интересны. 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
| 
		 
			 
			#5  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Хорошо. Сделаю. Вот тока по позже. Передохнуть надо. 
		
	
		
		
		
		
		
		
			Выше ещё две диаграммы ещё выложил. Более подробно. Но глядя на диаграммах, даёт понять, что если надо парсить текст, то лучше его преобразовать в массив Integer или Byte и работать с числами, а не со строками. Мляя. На последней диаграмме не написал "Количество сравнений за 5 сек" за место "Категория 1". Ну это просто заёп сказывается. Последний раз редактировалось seeman_tm, 28.11.2013 в 20:15.  | 
| 
		 
			 
			#6  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 А компилится в х32 или в х64 при сравнении int64? 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
| 
		 
			 
			#7  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Вот результаты сравнений Integer = Int64 и Int64 = Integer 
		
	
		
		
		
		
		
		
			![]() Немного переиначил тест. Теперь складывается 10 результатов одного и того же сравнения по 5 секунд и берётся средняя, то есть делим на 10. Цифры результатов вроде те же. Следовательно тест верный. Смотрите какая картина вырисовывается. Даже в последовательности, в которой передаются переменные в ветвление (If ... Then ....), сказывается в производительности. Несколько раз перепроверял. На лаги не похоже. Да и лаги быть не могут, у меня 4 ядра. 1 ядро чисто тест забивает. to Bargest, Если про винду ты, то Win 7 x64 (CodeGear Delphi 2009). А компилю как компилилось изначально после установки. Да я и не знаю где это менять. Последний раз редактировалось seeman_tm, 28.11.2013 в 22:39.  | 
| 
		 
			 
			#8  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Цитата: 
	
 Цитата: 
	
 Цитата: 
	
 Код: 
	function Test(Str1, Str2: String): Extended;
var
  i: Integer;
  tic1, tic2: DWORD;
begin
  UniqueString(Str1);
  UniqueString(Str2);
  tic1 := GetTickCount;
  for i := 1 to 500000000 do
  begin
    if Str1 = Str2 then;
  end;
  tic2 := GetTickCount;
  Result := (tic2 - tic1) / 1000;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessageFmt('Сравнение одинаковых строк заняло %g сек, а разных строк заняло %g сек',
    [Test('9797979797979797', '9797979797979797'),
     Test('9797979797979797', '7979797979797979')]);
end; | 
| 
		 
			 
			#9  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
	
	
		
			
			![]() Цитата: 
	
 Цитата: 
	
 Убери из кода Цитата: 
	
 p.s. Уже 4 часа утра. Пора спать. Последний раз редактировалось seeman_tm, 28.11.2013 в 23:07.  | 
| 
		 
			 
			#10  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Не стану создавать очередную тему. Зачем хламить форум. 
		
	
		
		
		
		
		
		
			Написал функцию. Цель её проста. Поиск подстрок в строке. Но основано на массивах байтов. Что, судя по выше выложенным диаграммам, даст наибольшую скорость поиска. О её плюсах. Скорость проведения поиска (Надо проверить на тестах и сравнить результаты с аналогичными функциями поиска уже подстроки в строке). Есть возможность задать функции несколько подмассивов сразу. (Функция возвращает позицию первого найденного подмассива и найденный подмассив) Поиск можно проводить с любой позиции. В случае, если надо провести поиск с учётом регистра символов, то имеется и эта возможность. Собственно сама функция. Код: 
	Type ArrayOfByte = Array Of Byte;
// MainSub - Массив искомых подмассивов
// Main - Массив в котором производится поиск подмассивов
// Finded - В случае успеха содержит найденный подмассив, в противном сдучае пуст
// Offset - Позиция с которой производить поиск подмассивов
// IgnoreCase - Игнорирование регистра
// Result - В случае успеха возвращает позицию с которой начинается подмассив в массиве
// (Массив и подмассивы начинаются с индекса 0
// В иных случаях в Result возвращается -1
Function TForm4.PosEx(Const MainSub: Array Of ArrayOfByte; Const Main: ArrayOfByte; Var Finded: ArrayOfByte; Const Offset: Cardinal = 0; Const IgnoreCase: Boolean = False): Integer;
var
  s: String;
  Index, IndexM, IndexS: Integer;
  Sub: Array Of ArrayOfByte; // Массив подмассивов, которые помещаются в Массив с учётом отсупа Offset
begin
  // Если отступ (Offset) превышает границы массива то выходим.
  if Offset > High(Main) then
    Begin
      SetLenGth(Finded, 0);
      Result := -1;
      Exit;
    End;
  // Перебираем подмассивы. Берём только те подмассивы, которые помещаются в Массив с учётом отсупа
  // и длинна больше 0
  for Index := Low(MainSub) to High(MainSub) do
    Begin
      // Если длинна массива больше 0
      // и подмассив помещается, то добавляем его в Sub
      if (LenGth(MainSub[Index]) > 0) and (LenGth(MainSub[Index]) <= ((LenGth(Main) - Offset) + 1)) then
           Begin
             SetLenGth(Sub, LenGth(Sub)+1);
             SetLenGth(Sub[High(Sub)], LenGth(MainSub[Index]));
             Move(MainSub[Index,Low(MainSub[Index])], Sub[High(Sub),Low(Sub[High(Sub)])], LenGth(Sub[High(Sub)]));
           End;
    End;
  // Если у нас нет ни одного подмассива прошедшего проверку
  if LenGth(Sub) = 0 then
    Begin
      SetLenGth(Finded, 0);
      Result := -1;
      Exit;
    End;
  for IndexM := OffSet to High(Main) do
    Begin
      for IndexS := Low(Sub) to High(Sub) do
         Begin
{           // Если подмассив больше не помещается в массив с учётом сдвига к концу массива, то убираем его из возможных
           While LenGth(Sub[IndexS]) > ((LenGth(Main) - Offset) + 1) Do
               Begin
                  Move(Sub[IndexS+1], Sub[IndexS], LenGth(Sub[IndexS])-IndexS);
                  SetLenGth(Sub, LenGth(Sub)-1);
                  Continue;
               End;  }
           for Index := Low(Sub[IndexS]) to High(Sub[IndexS]) do
             Begin
               if (Sub[IndexS,Index] <> Main[IndexM+Index]) Then
                  Begin
                     If Not(IgnoreCase) then
                        Break
                      Else
                        Begin
                          If ((Sub[IndexS,Index] >= 65) and (Sub[IndexS,Index] <= 90))
                                then
                                  Begin
                                    if (Sub[IndexS,Index] + 32 <> Main[IndexM+Index]) Then Break;
                                    Continue;
                                  End;
                          If ((Sub[IndexS,Index] >= 97) and (Sub[IndexS,Index] <= 122))
                                then
                                  Begin
                                    if (Sub[IndexS,Index] - 32 <> Main[IndexM+Index]) Then Break;
                                    Continue;
                                  End;
                        End;
                  End;
             End;
           if Index > High(Sub[IndexS]) then
            Begin
              Result := IndexM;
              Finded := Sub[IndexS];
              Exit;
            End;
         End;
    End;
  SetLenGth(Finded, 0);
  Result := -1;
End;Последний раз редактировалось seeman_tm, 29.11.2013 в 13:36.  | 
| 
		 
			 
			#11  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Хорошо, вот вариант без UniqueString: Код: 
	function Test(Str1, Str2: String): Extended;
var
  i: Integer;
  tic1, tic2: DWORD;
begin
  tic1 := GetTickCount;
  for i := 1 to 500000000 do
  begin
    if Str1 = Str2 then;
  end;
  tic2 := GetTickCount;
  Result := (tic2 - tic1) / 1000;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessageFmt('Сравнение одинаковых строк заняло %g сек, а разных строк заняло %g сек',
    [Test(IntToStr(9797979797979797), IntToStr(9797979797979797)),
     Test(IntToStr(9797979797979797), IntToStr(7979797979797979))]);
end; | 
| 
		 
			 
			#12  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 | 
| 
		 
			 
			#13  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Цитата: 
	
 Возвращаю твой совет: Цитата: 
	
  | 
| 
		 
			 
			#14  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 Это же нужно догадаться, измерять скорость с помощью GetTickCount. Думаешь после этого твои измерения имеют хоть какую-нибудь ценность? 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
| 
		 
			 
			#15  
			
			
			
			
		 
		
		
	 | 
||||
		
		
  | 
||||
| 
	
	
		
			
			 угу. QueryPerformanceCounter / QueryPerformanceFrequency хотя бы... 
		
	
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 |