Genel sınıflar kütüphanesi - hatalar, açıklamalar, sorular, kullanım özellikleri ve öneriler - sayfa 11

 

Bugünün ve muhtemelen bu haftanın son örneği: işlem numarası ile onu başlatan sipariş numarası arasındaki yazışma:

 //+------------------------------------------------------------------+
//|                                                     OrdersID.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property version    "1.00"
#include <Generic\HashMap.mqh>
input ulong FindTicketOrder = 82479995 ;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
{
   ulong tiks = GetMicrosecondCount ();
   HistorySelect ( 0 , TimeCurrent ());
   CHashMap< ulong , ulong > deals_orders;
   int total = HistoryDealsTotal ();
   ulong deal_id = 0 ;
   for ( int i = 0 ; i < total; i++)
   {
      deal_id = HistoryDealGetTicket (i);
       ulong order_id = HistoryDealGetInteger (deal_id, DEAL_ORDER );
      deals_orders.Add(deal_id, order_id);
   }
   ulong t2 = GetMicrosecondCount ()-tiks;
   printf ( "Время заполнения коллекции: " + ( string )t2 + " микросекунд" );
   tiks = GetMicrosecondCount ();
   ulong find_order = 0 ;
   if (deals_orders.TryGetValue(deal_id, find_order))
       printf ( "Сделке с номером " + ( string )deal_id + " Соответствует ордер с номером " + ( string )find_order);
   ulong delay = GetMicrosecondCount () - tiks;
   printf ( "Время выполнения запроса: " + ( string )delay + " микросекунд" );
}

Hesapta 10.000'den fazla işlemin olduğu benim durumumda, sonuç aşağıdaki gibidir:

 2017.12 . 08 17 : 56 : 05.184 OrdersID (SBRF Splice,M1)       Время заполнения коллекции: 145865 микросекунд
2017.12 . 08 17 : 56 : 05.184 OrdersID (SBRF Splice,M1)       Сделке с номером 44455231 Соответствует ордер с номером 83473421
2017.12 . 08 17 : 56 : 05.184 OrdersID (SBRF Splice,M1)       Время выполнения запроса: 9 микросекунд
 

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

Genel sınıf kitaplığı - hatalar, açıklama, sorular, kullanım ve öneriler

Vasiliy Sokolov , 2017.12.08 13:30

N çok küçükse, özet fonksiyonu tarafından elde edilen sayıyı her zaman N limitinde olacak şekilde normalleştiririz:

int index = GetHashCode(word) % ArraySize (m_array);

Bu noktaya kadar okudum. Vasily, Teşekkürler, vurgulanan hariç her şey açık. Bence kalanı normalleştirme olarak almak yanlış. Bu şekilde daha mantıklı görünüyor.

 int index = GetHashCode(word) * ArraySize (m_array) / HashSize ; // Надо бы и округлять, а не отбрасывать нецелочисленную часть, но не стал усложнять
 
Vasili Sokolov :

İşin aslı, bir sözlüğün boyutunun çoğu zaman bilinmemesidir. Basit bir örnek, diyelim ki bir Uzman Danışmanımız var. Tamamlanan işlemlerin kaydını tutar. Anlaşmanın tarihe geçmesinden sonra, bu anlaşmayı, diyelim ki uzmanın büyüsüyle ilişkilendirmek gerekiyor. Bunu yapmak için bir sözlük kullanmak mantıklıdır. İşlem numarasının anahtar (benzersiz tanımlayıcı) olarak kullanıldığı ve uzmanın sihirli numarasının değer olarak kullanıldığı durumlarda. Sorun şu ki, bir danışman başlatırken, 100 işlemimiz mi yoksa 1000 işlemimiz mi olacağını önceden belirlemek imkansız. Önceden ne kadar bellek ayırırsanız ayırın, yine de ya çok az ya da çok fazla olacaktır.

Görünüşe göre beynimi tamamen kırmadım. Vurgulananı açıklayabilir misiniz? hiç anlamıyorum.

 

alay konusu gibi görünüyor

 //+------------------------------------------------------------------+
//| Returns a hashcode for boolean.                                  |
//+------------------------------------------------------------------+
int GetHashCode( const bool value )
  {
   return ( ( value )? true : false );
  }


Dahil olmadan HashFunction.mqh. Bu yanlış.


Bu işlevin kullanımı nedir?

 template < typename T>
int GetHashCode(T value)
  {
//--- try to convert to equality comparable object  
   IEqualityComparable<T>*equtable= dynamic_cast <IEqualityComparable<T>*>(value);
   if (equtable)
     {
       //--- calculate hash by specied method   
       return equtable.HashCode();
     }
   else
     {
       //--- calculate hash from name of object
       return GetHashCode( typename (value));
     }
  }
Sonuçta, struct ve union için derlemek kolay olmayacak.
 
fxsaber :

Görünüşe göre beynimi tamamen kırmadım. Vurgulananı açıklayabilir misiniz? hiç anlamıyorum.

Şahsen ben bunu öyle anladım ki, anlaşma yaparken danışman sihirli sayıyı sözlüğe (diziye) anlaşma numarasına göre yazmalı, bu durumda hücre indeksi.

Gelecekteki anlaşmaların sayısı önceden bilinmemektedir ve büyüleri kaydetmek için zaten bir dizi bildirmiş olmamız gerekir. Görev, dizi için gerekli miktarda belleği önceden tahsis etmektir.

Tam bellek miktarını önceden tahsis etmek mümkün değildir. Bu, bir dizgeye büyüler yazabileceğiniz, sonunda alt dizgilerin sayısını alabileceğiniz, diziyi başlatabileceğiniz ve tüm alt dizgileri (sihirleri) oraya yazabileceğiniz anlamına gelir.

Her sihire daha fazla erişim, işlemin numarasına göre yapılacaktır.

Ben de hemen hemen böyle hayal ediyorum.

 
Vasili Sokolov :

Bugünün ve muhtemelen bu haftanın son örneği: işlem numarası ile onu başlatan sipariş numarası arasındaki yazışma:

Hesapta 10.000'den fazla işlemin olduğu benim durumumda, sonuç aşağıdaki gibidir:

Ve sizin durumunuzda klasik versiyon ne kadar geri dönüyor?

 ulong GetDealOrder( const ulong Deal )
{
   return ( HistoryDealSelect (Deal) ? HistoryDealGetInteger (Deal, DEAL_ORDER ) : 0 );
}


 2017.12 . 08 17 : 56 : 05.184 OrdersID (SBRF Splice,M1)       Время выполнения запроса: 9 микросекунд
Bu, printf'in çalışma zamanıdır.
 
fxsaber :

Bu işlevin kullanımı nedir?

Sonuçta, struct ve union için derlemek kolay olmayacak.

Başka bir aşırı yük eklendi

 template < typename T>
int GetHashCode(T &value)
  {
     return GetHashCode( typename (value));
  }


bununla yüzleşti

 //+------------------------------------------------------------------+
//| Returns a hashcode for string.                                   |
//+------------------------------------------------------------------+
int GetHashCode( const string value )
  {
   int len=StringLen( value );
   int hash= 0 ;
//--- check length of string
   if (len> 0 )
     {
       //--- calculate a hash as a fucntion of each char
       for ( int i= 0 ; i<len; i++)
         hash= 31 *hash+ value [i];
     }
   return (hash);
  }
Bu koddan mantıksal olarak gelen negatif sayıları döndürür. Bu iyi?
 
fxsaber :

Başka bir aşırı yük eklendi

 template < typename T>
int GetHashCode(T &value)
  {
     return GetHashCode( typename (value));
  }

Bana gelince, eğer bir nesne belirli bir arabirimi veya yöntemi uygulamıyorsa, o zaman sessizce susturmaktansa bir istisnayı açıkça ortaya koymak daha iyidir ve o zaman sorunların kaynağına ne kadar bakılacağı açık değildir.


Bu koddan mantıksal olarak gelen negatif sayıları döndürür. Bu iyi?

Kesinlikle normal.
Bir karma size hiçbir şeyi garanti etmez, yalnızca belirli bir dereceye kadar şu veya bu nesneyi karakterize eden bir sayıdır.
Bir tamsayıya ihtiyacınız varsa - uint almaktan çekinmeyin.

 
Sergey Dzyublik :

Bana gelince, eğer bir nesne belirli bir arabirimi veya yöntemi uygulamıyorsa, o zaman sessizce susturmaktansa bir istisnayı açıkça ortaya koymak daha iyidir ve o zaman sorunların kaynağına ne kadar bakılacağı açık değildir.

MqlTick ?

 
fxsaber :

MqlTick ?


T türü için GetHashCode şablon işlevi uzmanlığının açık bir uygulaması yoksa kodun ne yaptığını anlıyor musunuz?
 template < typename T>
int GetHashCode(T &value)
  {
     return GetHashCode( typename (value));
  }
Cevap: Kirli bir numara, çünkü uygulama eksikliği sorunu örtbas ediliyor. Aynı sınıfın tüm nesneleri aynı karma değerini döndürür.
Neden: