クールな仕事だ!これは、ずっと前にMQがeRAysに含めるべきだったもので、次のリリースでライブラリに含めることを願っています。ちなみに、MQL4でもすべて問題なく動作しています。本格的なポインタがないため、*CObjectの代わりに単純なデータ型を含めることは不可能だと理解していますが?それとも回避する方法があるのでしょうか?
2015.03.23 13:25:54.617 TestDict EURUSD,M1: 1000000 elements. Add: 1373; Get: 218 2015.03.23 13:25:52.644 TestDict EURUSD,M1: 950000 elements. Add: 1216; Get: 219 2015.03.23 13:25:50.833 TestDict EURUSD,M1: 900000 elements. Add: 1217; Get: 218 2015.03.23 13:25:49.069 TestDict EURUSD,M1: 850000 elements. Add: 1154; Get: 187 2015.03.23 13:25:47.424 TestDict EURUSD,M1: 800000 elements. Add: 1092; Get: 187 2015.03.23 13:25:45.844 TestDict EURUSD,M1: 750000 elements. Add: 1061; Get: 171 2015.03.23 13:25:44.320 TestDict EURUSD,M1: 700000 elements. Add: 1107; Get: 156 2015.03.23 13:25:42.761 TestDict EURUSD,M1: 650000 elements. Add: 1045; Get: 140 2015.03.23 13:25:41.304 TestDict EURUSD,M1: 600000 elements. Add: 1014; Get: 156 2015.03.23 13:25:39.915 TestDict EURUSD,M1: 550000 elements. Add: 920; Get: 125 2015.03.23 13:25:38.665 TestDict EURUSD,M1: 500000 elements. Add: 702; Get: 109 2015.03.23 13:25:37.693 TestDict EURUSD,M1: 450000 elements. Add: 593; Get: 93 2015.03.23 13:25:36.836 TestDict EURUSD,M1: 400000 elements. Add: 577; Get: 78 2015.03.23 13:25:36.025 TestDict EURUSD,M1: 350000 elements. Add: 561; Get: 78 2015.03.23 13:25:35.247 TestDict EURUSD,M1: 300000 elements. Add: 515; Get: 78 2015.03.23 13:25:34.557 TestDict EURUSD,M1: 250000 elements. Add: 343; Get: 63 2015.03.23 13:25:34.063 TestDict EURUSD,M1: 200000 elements. Add: 312; Get: 47 2015.03.23 13:25:33.632 TestDict EURUSD,M1: 150000 elements. Add: 281; Get: 31 2015.03.23 13:25:33.264 TestDict EURUSD,M1: 100000 elements. Add: 171; Get: 16 2015.03.23 13:25:33.038 TestDict EURUSD,M1: 50000 elements. Add: 47; Get: 16
作者に拍手を送りたい!これはMQがもっと前にMQL5/Include/Arraysに含めるべきだったものだ。ちなみに、MQL4でもすべて問題なく動作しています。本格的なポインタがないため、*CObjectの代わりに単純なデータ型を含めることは不可能だと理解していますが?それとも何かうまくいく方法があるのでしょうか?
うまくいくよ。ボックス化/アンボックス化のメカニズムとテンプレートの助けを借りれば。考え方としては、各基底型はKeyValuePairBaseコンテナに詰め込まれる。解凍して対応する型を返すのは、GetObjectByKey型の内部関数で行われる:
template<typename Type, typename T>
Type GetObjectByKey(T key);重要なことは、基本型を使用することで性能上の利点は得られないが、より便利になるということである。
テンプレートに基づいて、CObjectの 代わりに基本的なMQL型の1つを格納するCDictionaryBaseを作成しようとしました。残念ながらうまくいきませんでした。関数がテンプレート型を返すことができないのです。残念だ:
//+------------------------------------------------------------------+ //|TestDictBase.mq5 //|著作権 2015, Vasiliy Sokolov.| //|http://mql5.commql5.com //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Vasiliy Sokolov." #property link "http://www.mql5.com" #property version "1.00" #include <Dictionary.mqh> #include <DictionaryBase.mqh> //+------------------------------------------------------------------+ //| スクリプト番組開始機能| //+------------------------------------------------------------------+ void OnStart() { //--- CDictionaryBase base; base.AddValue("Pi", 3.14159); double pi = (double)base.GetValueByKey("Pi"); printf(DoubleToString(pi, 5)); //base.AddObject( } //+------------------------------------------------------------------+
could not deduce template argument #1 TestDictBase.mq5 19 29 could not deduce template argument #0 DictionaryBase.mqh 404 25 possible loss of data due to type conversion DictionaryBase.mqh 133 10 possible loss of data due to type conversion DictionaryBase.mqh 135 10 possible loss of data due to type conversion DictionaryBase.mqh 137 10 ...
//+------------------------------------------------------------------+ //| キーによってオブジェクトを返します。| //+------------------------------------------------------------------+ template<typename T, typename C> C CDictionaryBase::GetValueByKey(T key) { if(!ContainsKey(key)) return NULL; return m_current_kvp.GetValue(); }
残念だ。
そのため、それぞれの基本型に対して基本コンテナを作成するか、基本型のコンテナだけを作成する必要がある:CDouble、CLong、CIntなどだ。
今、私はテンプレートに基づいてCObjectの代わりに基本的なMQL型の1つを格納するCDictionaryBaseを作成しようとしました。残念ながら、関数がテンプレート型を返すことができないため、失敗しました。
返すことはできる。しかし、返される値の型を自動的に推測することはできません。
擬似パラメータという形で小さな松葉杖を使うことができます。
template<typename T, typename C> C CDictionaryBase::GetValueByKey(T key, C) { if(!ContainsKey(key)) return NULL; return m_current_kvp.GetValue(); }
そうだ。しかし、返される値の型を自動的に推測することはできない。
擬似パラメータという形で小さな松葉杖を使うことができる。
実際の松葉杖はどこにあるのか?
2つ目のパラメータが追加されました
パフォーマンスを比較してみましたか?ソートされた文字列配列のバイナリサーチに対する優位性は、どの程度のデータサイズから始まるのでしょうか?
正確なテストはしていませんが、私の観察によれば、数万要素からスピードの優位性が現れ始めます。つまり、100-10,000個の要素を持つ日常的なタスクでは、パフォーマンスの向上は望めない。
ここでもうひとつ重要なのは、コンテナでの作業の利便性である。要素を検索するために追加のメソッドを書く必要はない。辞書を使った日常的なタスクの多くは、実装が何倍も簡単になる。インデックスを検索するために要素を作成し、対応するインデックスによって必要な要素を取得する、などといったことが不要になるのだ。
s.s. しかし、ここで私は、性能は要素の挿入と検索にかかる時間の合計として測定されるべきだと思った。そして、CArrayObjの 中でソートされた項目を検索するのがかなり高速な操作だとすると、挿入は本当に面倒なことになる。高速な検索には順序性が必要なので、挿入の可能性を排除することはできない。
とても興味深く、辞書がとても便利で使いやすいデータオーガナイザーであることは明らかです。
ありがとう。
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
新しい記事 MQL5 クックブック: 連想配列またはクイック データアクセスのための辞書の実装 はパブリッシュされました:
本稿はユニークなキーによってエレメントへのアクセスが可能となる特殊なアルゴリズムについて説明します。キーとして任意のベースデータタイプが使用可能です。たとえば文字列や整数変数として表すことが可能です。そのようなデータのコンテナは一般的に辞書または連想配列と呼ばれます。それにより課題解決に対するより簡単で効果的な方法が提供されます。
本稿は情報を便利に格納するためのクラスについて説明します。すなわち連想配列または辞書です。このクラスによりキーによってエレメントへのアクセスが可能となります。
連想配列は通常の配列に似ています。ただインデックスの代わりに連想配列はいくつか独自のキーを使用します。たとえば列挙 ENUM_TIMEFRAMES やテキストなどです。キーが何を表すかは問題ではありません。重要なのはキーのユニークさです。このデータ格納アルゴリズムは多くのプログラミング側面を大幅にシンプル化します。
たとえば、エラーコードを取りエラーに相当するテキストを出力する関数は以下のようなものとなるでしょう。
あとでこのコードの特別な機能について詳しくみていきます。
連想配列の内部ロジックを直接説明する前に、データ格納の主要な2とおりの方法を考察しようと思います。すなわち配列とリストです。われわれの辞書 はこの2とおりのデータタイプを基にしています。それがそれらの特定の機能をよく理解しなければならない理由です。第1章はデータタイプについて説明しま す。第2章では連想配列とそれと連携するメソッドについて説明します。
作者: Vasiliy Sokolov