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

 
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.

  • MQL5'te arayüz yoktur.
  • MQL5'te istisna yoktur.

Sonuç olarak, evet, asil bir tatar yayı ve kodla ilgili sorun hakkında bariz bir sessizlik ortaya çıkıyor.

 
Vasili Sokolov :

Aynı nedenle, karşılaştırma yanlıştır. Bir ticaret ortamı elde etmek için özel CHashMap'i nasıl karşılaştırabilir ve sistem işlevleriyle nasıl çalışabilirsiniz?

Demir argümanları kabul etmediğiniz için optimal olmayan kod yazmaya devam edin.

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

fxsaber , 2017.12.08 22:46

Daha gerçekçi bir test durumu için (2000 işlem ve 1.000.000 tek geçmiş erişimi), sonuç şöyle görünür

 2017.12 . 05 00 : 00 : 00    Time [ Print (SumProfit(Deals,GetDealProfitFull))] = 122969
2017.12 . 05 00 : 00 : 00    Time [SetHashMap()] = 816
2017.12 . 05 00 : 00 : 00    4829800340.792288
2017.12 . 05 00 : 00 : 00    Time [ Print (SumProfit(Deals,GetDealProfitHashClear))] = 23852
2017.12 . 05 00 : 00 : 00    Time [ HistorySelect ( 0 , INT_MAX )] = 1
2017.12 . 05 00 : 00 : 00    4829800340.792288
2017.12 . 05 00 : 00 : 00    Time [ Print (SumProfit(Deals,GetDealProfitClear))] = 114427

Geçiş başına yaklaşık 100 ms tasarruf! Örneğin, 10.000 tam geçiş için Optimizasyon yaparsak, Hash sürümü 15 dakika daha hızlı biter.

Vasili Sokolov :

Sonuç olarak, evet, asil bir tatar yayı ve kodla ilgili sorun hakkında bariz bir sessizlik ortaya çıkıyor.

Her ikisi de bir tür saçmalık yazdı, HashMap'in şu anki haliyle struct ve union için çalışmadığını tek bir gram anlamadı.
 
fxsaber :

Demir argümanları kabul etmediğiniz için optimal olmayan kod yazmaya devam edin.

Her ikisi de bir tür saçmalık yazdı, HashMap'in şu anki haliyle struct ve union için çalışmadığını tek bir gram anlamadı.

Sevgili, bir şey içiyorsanız ve muhatabın gönderisini dikkatlice okuyamıyorsanız , o zaman bunlar sizin sorunlarınızdır ve herkesin değil, sadece hastanın tedavi edilmesi gerekir.
Tekrar ediyoruz: kimse yapı ve birlik hakkında bir konuşma yapmadı, kimse bu konudaki fikirlerinize meydan okumadı ....


Özellikle kodun bu şartlarıyla ilgiliydi.
Standart kitaplıktan:

 //+------------------------------------------------------------------+
//| Returns a hashcode for custom object.                            |
//+------------------------------------------------------------------+
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));
     }
  }
//+------------------------------------------------------------------+



Ve eklediniz:

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

fxsaber , 2017.12.08 21:17

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

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


Neyi iletmeye çalışıyordun:
Karma, kapsayıcıdaki öğelerin aranmasını hızlandırmak için kullanılır. O(1) hız - kapsayıcıya eklenen öğelerin sayısına bağlı değildir.
Durum - kullanıcı kendi sınıfını anahtar olarak kullanır.
1) Arayüzlerin çoklu kalıtımı olmaması nedeniyle ( MQL5'te arayüz yoktur ), kullanıcı IEqualityComparable'dan miras alamaz ;
2) Kullanıcı ayrıca GetHashCode şablon işlevi için açık bir belirtim belirtmeyi de unutur.

Sonuçlar - kullanıcı bir şeyi atladığı konusunda hiçbir şekilde bilgilendirilmez ve kod, istisnalar atılmadan başarıyla yürütülür ( MQL5'te istisna yoktur ).
Hız, ortalama karma hesaplama sabitiyle O(1)'den, karşılaştırma için yeterince büyük bir sabitle O(n)'ye düşer.
Yalnızca kaptaki çok sayıda öğeyle ve uygulamada bir darboğaz aramak için çok zaman harcayarak
, kullanıcı sorunların nedenini bulabilir - sınıfı için açık bir GetHashCode belirtimi olmaması.
Alınma, teşekkürler.

 
Ve yine de, neden ticaret için tüm bu inkar edilemez havalı şeyler?
Pekala, hayatımda asla tarihten binlerce anlaşma almak, onları doğuran emirleri aramak vb. zorunda kalmadım.
 
Sergey Dzyublik :

Sevgili, bir şey içiyorsanız ve muhatabın gönderisini dikkatlice okuyamıyorsanız , o zaman bunlar sizin sorunlarınızdır ve herkesin değil, sadece hastanın tedavi edilmesi gerekir.

Eldiven, görünüşe göre, sigara içenler tarafından kapatılamaz.

 #include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280
#include <crc64.mqh>       // https://www.mql5.com/en/blogs/post/683577

template < typename T>
int GetHashCode( T &value )
{
   ulong crc = 0 ;

   return (( int )crc64(crc, _R(value).Bytes, sizeof (T)));
}

template < typename T>
int GetHashCode( T &value[] )
{
   ulong crc = 0 ;

   return (( int )crc64(crc, _R(value).Bytes, ArraySize (value) * sizeof (T)));
}
 
Bu konu ile ilgili olmayan yorumlar " Algoritmalar, karar yöntemleri, performanslarının karşılaştırılması " bölümüne taşınmıştır.
 

Başlangıçta daldan bir örnek derlemesi yapmak planlanmamasına rağmen, algoritmaları henüz uygulamalarında kullanmayanların neden kullanışlı ve en önemlisi basit olduğunu anlamaları için bu tür birkaç örnek ekleme ihtiyacı hissediyorum.

 

Örnek 1: Bir çalışma zamanı hatasını dize açıklamasıyla ilişkilendirme

Oldukça sık, sayısal sabitleri dize değişmezlerine dönüştürmeniz gerekir. Örneğin, hata kodlarını, hatanın özünü ortaya çıkaran net bir yazıyla çoğaltmak daha iyidir. Bu çok zor bir görev değildir ve genellikle özel bir işlev veya bir anahtar durumu veya bunun gibi bir dizi ifs ile çözülür:

 string ErrorDescription( int error_code)
   if (error_code == 40001 )
       return ( "Неожиданная внутренняя ошибка" );
   //...
}

Böyle bir kararın yaşam hakkı vardır. Ama biz CHashMap'e dayalı bir çözüm anlatacağız ve sağladığı avantajları göstereceğiz.

Bu algoritma şöyle görünebilir:

  • <hata kodu - hata açıklaması> biçiminde bir ilişkisel dizi oluşturun;
  • Olası hata kodlarını ve açıklamalarını bu sözlüğe ekliyoruz;
  • Doğrudan ve aracılar olmadan, koduna göre hatanın tanımını almak için sözlüğe dönüyoruz
Bu kod şöyle görünür:

 //+------------------------------------------------------------------+
//|                                                     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 ;

CHashMap< int , string > ErrorDescription;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void AddDescriptionInfo( void )
{
   // Добавим коды системных ошибок
   ErrorDescription.Add( 0 ,     "Операция выполнена успешно" );
   ErrorDescription.Add( 4001 , "Неожиданная внутренняя ошибка" );
   ErrorDescription.Add( 4002 , "Ошибочный параметр при внутреннем вызове функции клиентского терминала" );
   ErrorDescription.Add( 4003 , "Ошибочный параметр при вызове системной функции" );
   ErrorDescription.Add( 4004 , "Недостаточно памяти для выполнения системной функции" );
   // Можно добавлять константные значения вместо чисел
   ErrorDescription.Add( ERR_STRUCT_WITHOBJECTS_ORCLASS , "Структура содержит объекты строк и/или динамических массивов и/или структуры с такими объектами и/или классы" );
   ErrorDescription.Add( ERR_INVALID_ARRAY , "Массив неподходящего типа, неподходящего размера или испорченный объект динамического массива" );   
   ErrorDescription.Add( ERR_ARRAY_RESIZE_ERROR , "Недостаточно памяти для перераспределения массива либо попытка изменения размера статического массива" );
   //...
}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
{
   AddDescriptionInfo();
   string last_error = "" ;
   ErrorDescription.TryGetValue( GetLastError (), last_error);
   printf ( "Последняя ошибка: " + last_error);
}
//+------------------------------------------------------------------+

Hata kodları doldurulduktan sonra farklı fonksiyonlar kullanılmadan tek satır ile ulaşılır. Ayrıca, bazı durumlarda bu kodun birkaç düzine if'den bile daha hızlı çalışacağını hatırlatmama izin verin, çünkü istenen hataya adresleme, ortalama O (1) hızıyla doğrudan gerçekleşir.

 
Vasili Sokolov :

Hata kodları doldurulduktan sonra farklı fonksiyonlar kullanılmadan tek satır ile ulaşılır.

ErrorToString'in yine de yazılması gerekecek. Bu nedenle, bir artı olarak argüman zayıftır.

Ayrıca, bazı durumlarda bu kodun birkaç düzine if'den bile daha hızlı çalışacağını hatırlatmama izin verin, çünkü istenen hataya adresleme, ortalama O (1) hızıyla doğrudan gerçekleşir.

Ama bu kesin bir artı.

 

Bir sözlük aracılığıyla önerilen çözümde, başlıcaları ilk bakışta tamamen açık olmayan çeşitli avantajlar vardır. Böyle bir kod yazdığımızda:

 string ErrorDescription( int error_code)
   if (error_code == 40001 )
       return ( "Неожиданная внутренняя ошибка" );
   //...
}

Ardından, hata kodlarını EA kodunun kendisine sıkıca dikeriz. Bir sözlüğü doldurduğumuzda, bunu dinamik olarak yaparız, yani. program yürütme sırasında. Dinamik yaklaşım bize büyük esneklik sağlıyor. Örneğin, ErrorsCode.txt gibi özel bir dosyada hata kodları bulunabilir:

 4001 ;Операция выполнена успешно
4002 ;Неожиданная внутренняя ошибка
4003 ;Ошибочный параметр при вызове системной функции
...

Başlatma sırasında, program bu dosyayı okuyabilir ve sözlüğü gerekli kodlarla doldurabilir ve ardından dizenin istenen sürümünü kullanıcıya döndürebilir. Bu tür birkaç dosya olabilir: her dil için bir dosya. Bu şekilde, kullanıcının diline bağlı olarak hata kodlarının kendi dilinde görüntülendiği yerelleştirme gerçekleştirilebilir. Ayrıca, kullanıcının kendisi bu hata kodlarını bir kez kendi ana diline çevirebilir ve programın kendisi istenen mesajı kendi dilinde göstermeyi "öğrenir". Menü çevirisi bir metin dosyasında bulunduğunda ve ayarlara bağlı olarak program onu yüklediğinde, çoğu programın yerelleştirilmesi bu şekilde yapılır. Onlar. programı yeniden derlemeden ve algoritmasını değiştirmeden, sonuçlarının sunumunu önemli ölçüde etkileyebiliriz.

Neden: