일반 클래스 라이브러리 - 버그, 설명, 질문, 사용 기능 및 제안 사항 - 페이지 35

 
Renat Fatkhullin :

거의 불가능하고 문제가 발생하더라도 액세스는 여전히 매우 효과적입니다.

효율성의 모든 수준에서 충돌은 나쁩니다. 답변 해주셔서 감사합니다. 고려하겠습니다.

 
fxsaber :

효율성의 모든 수준에서 충돌은 나쁩니다. 답변 해주셔서 감사합니다. 고려하겠습니다.

정의에 따르면 충돌이 없는 해시맵은 없습니다.

 
fxsaber # :

충돌 질문입니다. 이 경우 충돌이 발생할 수 있습니까?

27,000개의 레코드가 생성된 경우.

특히 컬렉션의 성장(크기 조정)과 함께 지속적으로 직면하게 될 것입니다. 해시는 추가로 갱 번호로 잘리고 항상 제한된 수가 있기 때문에(이상적으로는 용량과 동일).

여기에서 결론:

1. 맵의 경우 중요한 것은 해시 함수의 암호화 강도가 아니라 속도가 중요합니다. 해시 함수는 좋은 랜덤을 제공하기에 충분하며 그게 전부입니다.

2. 크기 조정은 어떤 방법으로든 피하는 것이 가장 좋습니다. 주요 단점을 가져오는 것은 크기 조정입니다. 해시 함수 충돌이 아닙니다. 가능하면 미리 결정된 수의 요소로 컬렉션을 초기화합니다. 정확히 알지 못하더라도 대략적인 숫자를 표시하십시오. 이것은 알고리즘에 큰 도움이 될 것입니다.

3. 충돌은 표준 압축 메커니즘입니다. 충돌을 통해 ID가 159, 4'569'209, 29'459'876인 세 개의 레코드를 저장할 수 있습니다. 예를 들어, 마지막 두 값이 모두 해당하더라도 길이가 30,000,000이 아니라 길이가 3인 배열에 인덱스 2의 밴드로

 
Vasiliy Sokolov # :

2. 크기 조정은 어떤 방법으로든 피하는 것이 가장 좋습니다. 주요 단점을 가져오는 것은 크기 조정입니다. 해시 함수 충돌이 아닙니다. 가능하면 미리 결정된 수의 요소로 컬렉션을 초기화합니다. 정확히 알지 못하더라도 대략적인 숫자를 표시하십시오. 이것은 알고리즘에 큰 도움이 될 것입니다.

예를 들어 보여주세요.

지금은 이것만 사용합니다.

 //+------------------------------------------------------------------+
//| Adds the specified key and value to the map.                     |
//+------------------------------------------------------------------+
template < typename TKey, typename TValue>
bool CHashMap::Add(TKey key,TValue value);
 //+------------------------------------------------------------------+
//| Gets the value associated with the specified key.                |
//+------------------------------------------------------------------+
template < typename TKey, typename TValue>
bool CHashMap::TryGetValue(TKey key,TValue &value);
 
fxsaber # :

예를 들어 보여주세요.

지금은 이것만 사용합니다.

CHashMap 컬렉션을 생성할 때 용량 매개변수를 받는 생성자 중 하나를 사용하세요. 크기 조정 중 성능에 어떤 일이 발생하는지에 대해서는 CDicionary에 대한 내 기사를 참조하십시오. 이 알고리즘에 대한 완전한 분석이 있습니다.

 

매우 특이한 CHashMap 동작을 발견했습니다.

 // Демонстрация невозможности доступа по ключу после первого добавления.

#include <Generic\HashMap.mqh>

void OnStart ()
{
   // Отсортированный массив неповторяющихся цен.
   const double Array[] =
{ 1.70682 , 1.70691 , 1.70700 , 1.70709 , 1.70710 , 1.70717 , 1.70721 , 1.70742 , 1.70749 , 1.70752 , 1.70757 , 1.70766 , 1.70768 , 1.70769 , 1.70771 , 1.70773 , 1.70774 , 1.70777 ,
 1.70782 , 1.70785 , 1.70786 , 1.70797 , 1.70804 , 1.70808 , 1.70813 , 1.70850 , 1.70868 , 1.70879 , 1.70881 , 1.70883 , 1.70895 , 1.70905 , 1.70918 , 1.70921 , 1.70936 , 1.70962 ,
 1.70966 , 1.71022 , 1.71027 , 1.71047 , 1.71056 , 1.71080 , 1.71081 , 1.71093 , 1.71096 , 1.71109 , 1.71112 , 1.71119 , 1.71120 , 1.71127 , 1.71128 , 1.71135 , 1.71136 , 1.71138 ,
 1.71145 , 1.71147 , 1.71148 , 1.71150 , 1.71155 , 1.71159 , 1.71162 , 1.71164 , 1.71168 , 1.71172 , 1.71203 , 1.71204 , 1.71210 , 1.71269 , 1.71289 , 1.71293 , 1.71299 , 1.71334 ,
 1.71337 , 1.71343 , 1.71357 , 1.71358 , 1.71367 , 1.71371 , 1.71374 , 1.71380 , 1.71402 , 1.71410 , 1.71414 , 1.71425 , 1.71426 , 1.71427 , 1.71429 , 1.71430 , 1.71446 , 1.71474 ,
 1.71477 , 1.71518 , 1.71521 , 1.71558 , 1.71587 , 1.71588 , 1.71617 , 1.71620 , 1.71624 , 1.71626 , 1.71629 , 1.71635 , 1.71644 , 1.71654 , 1.71655 , 1.71658 , 1.71661 , 1.71664 ,
 1.71689 , 1.71700 , 1.71712 , 1.71718 , 1.71727 , 1.71752 , 1.71769 , 1.71775 , 1.71780 , 1.71782 , 1.71786 , 1.71792 , 1.71795 , 1.71797 , 1.71798 , 1.71801 , 1.71815 , 1.71827 ,
 1.71832 , 1.71835 , 1.71841 , 1.71869 , 1.71895 , 1.71908 , 1.71951 , 1.71984 , 1.71992 , 1.72008 , 1.72086 , 1.72132 , 1.72147 , 1.72204 , 1.72208 , 1.72212 , 1.72215 , 1.72227 ,
 1.72230 , 1.72233 , 1.72234 , 1.72336 , 1.72374 , 1.72378 , 1.72381 , 1.72405 , 1.72454 , 1.72464 , 1.72477 , 1.72488 , 1.72541 , 1.72553 , 1.72562 , 1.72588 , 1.72625 , 1.72651 ,
 1.72653 , 1.72671 , 1.72679 , 1.72685 , 1.72720 , 1.72783 , 1.72849 , 1.72852 , 1.72854 , 1.72925 , 1.72927 , 1.72938 , 1.72953 , 1.72956 , 1.72960 , 1.72970 , 1.72975 , 1.72979 ,
 1.72996 , 1.73014 , 1.73028 , 1.73034 , 1.73050 , 1.73056 , 1.73084 , 1.73085 , 1.73119 , 1.73137 , 1.73176 , 1.73278 , 1.73328 , 1.73337 , 1.73344 , 1.73345 , 1.73362 , 1.73377 ,
 1.73385 , 1.73399 , 1.73401 , 1.73405 , 1.73425 , 1.73432 , 1.73445 , 1.73446 , 1.73447 , 1.73451 , 1.73458 , 1.73468 , 1.73491 , 1.73512 , 1.73515 , 1.73516 , 1.73537 , 1.73545 ,
 1.73553 , 1.73580 , 1.73581 , 1.73598 , 1.73611 , 1.73630 , 1.73635 , 1.73643 , 1.73658 , 1.73678 , 1.73694 , 1.73695 , 1.73698 , 1.73712 , 1.73713 , 1.73721 , 1.73746 , 1.73748 ,
 1.73750 , 1.73751 , 1.73781 , 1.73782 , 1.73789 , 1.73821 , 1.73843 , 1.73845 , 1.73854 , 1.73857 , 1.73858 , 1.73861 , 1.73874 , 1.73892 , 1.74003 , 1.74060 , 1.74062 };

  CHashMap< double , int > Index; // Будем по double-ключу хранить int-значения.
  
   for ( int i = ArraySize (Array) - 1 ; i >= 0 ; i--)
    Index.Add( NormalizeDouble (Array[i], 5 ), 0 ); // Каждую цену массива используем в качестве ключа.
    
   // Все это было подготовкой, чтобы продемонстрировать поведение ниже.
  
   const double Price = 1.75141 ; // Берем новую цену.
  
   if (Index.Add(Price, 0 )) // Если получилось добавить ее в качестве ключа.
  {
     int Value = 0 ;

     Print (Index.TryGetValue(Price, Value)); // (false) Проверяем, получается ли посмотреть данные по этому ключу.
    
     if (Index.Add(Price, 0 )) // Пробуем повторно добавить в качестве ключа
       Print (Index.TryGetValue(Price, Value)); // (true) Проверяем, получается ли посмотреть данные по этому ключу.
  }
}


 false
true

키가 추가되고 있는 것으로 나타났지만 아무 것도 읽을 수 없습니다. 그러나 키를 다시 추가하는 즉시 읽을 수 있게 됩니다!

버그인가요?


예에서 가격 1.75141 을 다른 가격으로 바꾸면 올바르게 작동합니다.


ZY 디버깅 없이 거대한 코드에서 이 동작을 식별하고 간결한 예제를 만드는 것은 지옥같이 어려웠습니다.

 
Vasiliy Sokolov # :

가능하면 미리 결정된 수의 요소로 컬렉션을 초기화합니다. 정확히 알지 못하더라도 대략적인 숫자를 표시하십시오. 이것은 알고리즘에 큰 도움이 될 것입니다.

위의 예에서는 생성자를 통해 용량을 설정하려고 했습니다. 특정 용량 값부터 예제가 올바르게 작동하기 시작합니다.

하지만 우연의 일치라고 생각합니다.

 
fxsaber # :

매우 특이한 CHashMap 동작을 발견했습니다.


키가 추가되고 있는 것으로 나타났지만 아무 것도 읽을 수 없습니다. 그러나 키를 다시 추가하는 즉시 읽을 수 있게 됩니다!

버그인가요?


예에서 가격 1.75141 을 다른 가격으로 바꾸면 올바르게 작동합니다.


ZY 디버깅 없이 거대한 코드에서 이 동작을 식별하고 간결한 예제를 만드는 것은 지옥같이 어려웠습니다.

수정됨, 오늘 릴리스에 포함될 예정입니다.
 
MetaQuotes # :
수정됨, 오늘 릴리스에 포함될 예정입니다.

고맙습니다! 수정이 보이네요.


 
fxsaber # :

위의 예에서는 생성자를 통해 용량을 설정하려고 했습니다. 특정 용량 값부터 예제가 올바르게 작동하기 시작합니다.

하지만 우연의 일치라고 생각합니다.

예, 결함에 결함이 있습니다. Generic 사용을 강력히 권장하지 않습니다.