Mikhail Sukhov
|
Дата: 26.03.2011
aspirant Dictionary отсортировал бы свои элементы по алфавиту (ключи ведь string). Ты путаешь с SortedDictionary. И то там не по алфавиту... Это хеш алгоритм. Там сортировка не нужна. Группировка значения идет по хэшу ключа. Соответственно, когда обращаемся по ключу, сначала берется его хэш (PlazaColumn.GetHashCode) и получаются все значения, соответствующие хэшу. Операция O(1). И далее, если у нас коллизия, перебором всех ключей идет сравнение (PlazaColumn.Equals) и находится первый попавшийся (ага, уникальность там не проверяется). Итого, в лучшем варианте O(1). В худшем O(n). Но чтобы добиться последнее, надо еще постараться.[smile]
|
|
Спасибо:
|
|
|
|
|
aspirant
|
Дата: 26.03.2011
Mikhail Sukhov aspirant Dictionary отсортировал бы свои элементы по алфавиту (ключи ведь string). Ты путаешь с SortedDictionary. И то там не по алфавиту... Это хеш алгоритм. Там сортировка не нужна. Группировка значения идет по хэшу ключа. Соответственно, когда обращаемся по ключу, сначала берется его хэш (PlazaColumn.GetHashCode) и получаются все значения, соответствующие хэшу. Операция O(1). И далее, если у нас коллизия, перебором всех ключей идет сравнение (PlazaColumn.Equals) и находится первый попавшийся (ага, уникальность там не проверяется). Итого, в лучшем варианте O(1). В худшем O(n). Но чтобы добиться последнее, надо еще постараться.[smile] Да, насчет сортировки я был не прав.
|
|
Спасибо:
|
|
|
|
|
Mikhail Sukhov
|
Дата: 26.03.2011
|
|
|
|
aspirant Я изменил класс PlazaListener. Посмотри, пожалуйста, нужны твои комментарии + желательно кусок псевдокода - твое видение, как пользователь создает таблицу с набором колонок для передачи ее в PlazaListener. Посмотрел и доделал кое-что. Рассмешило название PlazaPartColumns. Долго думал, что за "часть". Оказалось, это Партфэл, дарагой! Что осталось до переделать:
- Сейчас PlazaListener создается в самом начале со всеми колонками. Как я уже писал, использовать надо только те колонки, что определены схемами PlazaTable.Columns.
- PlazaListener выглядит как лишний класс (возможно, что в него потом будет засунута еще какая-то логика, если да, то какая?). Что он делает сейчас. Берет данные из PlazaStream и передает их в PlazaTrader. Тоесть, такой бюрократически посредник, который бумажки из стола на стол несет.
- enum TableName лучше сделать статическим классом со строковыми константами. Я так понял, такие безобразные названия нужны лишь для того, чтобы ini файлы создавать? Если да, то по логике простой. Мы создаем текстовый файл, используем string. Вся логика в имени полей TableName - приведение в string... Так может тогда сразу сделать string?
- Давайте подумаем насчет фильтрации. Сейчас это выглядит как то не очень. Аспирант, ты же вроде как уже что-то делал по фильтрам?
- PlazaSchemaParser предлагаю упрятать в PlazaTableSerializer.
|
|
Спасибо:
|
|
|
|
|
skuvv
|
Дата: 26.03.2011
aspirant skuvv К примеру я сравнил проект со своей старой программой plaza2, данные в текущий s# проект поступают медленнее на 6-10мс(время снимал с OnNewSecurityChanged к примеру).
Получается, ты делал свою реализацию PlazaTrader? Нет у меня не интерфейс как в s#, а напрямую работа c потоками и событиями
|
|
Спасибо:
|
|
|
|
|
Mikhail Sukhov
|
Дата: 26.03.2011
skuvv aspirant skuvv К примеру я сравнил проект со своей старой программой plaza2, данные в текущий s# проект поступают медленнее на 6-10мс(время снимал с OnNewSecurityChanged к примеру).
Получается, ты делал свою реализацию PlazaTrader? Нет у меня не интерфейс как в s#, а напрямую работа c потоками и событиями Может выложить это ввиде отдельного теста для сравнения перфоманса? Насчет OnNewSecurityChanged - конечно. Если вместо поиска по словарю устраивать Exist Find и т.д., то я не удивлюсь и пол минутными задержками.[smile]
|
|
Спасибо:
|
|
|
|
|
aspirant
|
Дата: 26.03.2011
|
|
|
|
Mikhail Sukhov Сейчас PlazaListener создается в самом начале со всеми колонками. Как я уже писал, использовать надо только те колонки, что определены схемами PlazaTable.Columns. Как клиентский код создает таблицу с колонками и схемами? Твое видение с куском кода. Mikhail Sukhov enum TableName лучше сделать статическим классом со строковыми константами. Я так понял, такие безобразные названия нужны лишь для того, чтобы ini файлы создавать? Если да, то по логике простой. Мы создаем текстовый файл, используем string. Вся логика в имени полей TableName - приведение в string... Так может тогда сразу сделать string? Этот enum был служебным, для внутреннего пользования. Клиенту его можно не показывать. Зачем я его сделал? Когда нужно набить пару десятков классов, enum + intellisense здорово помогает. Потом подстраховка от случайное опечатки в string. Сам я его не набивал: вместо этого пропарсил папку со всеми схемами. Вообще PlazaTable сейчас и есть то, что ты предлагаешь. За исключением полей метаданных все остальные методы закомментены (причем, делал это не я). Можно сделать вот так: Код// вместо: public TableName SystemName { get; private set; } public string SystemName { get{ _systemName.ToString(); } Mikhail Sukhov Давайте подумаем насчет фильтрации. Сейчас это выглядит как то не очень. Я вообще собирался это делать внутри PlazaListener, но пока думал, skuvv успел привинтить свой фильтр[smile]. Что насчет методов RegisterSecurity/UnRegisterSecurity? С помощью них будем включать фильтрацию или они нужно для чего-то другого? Mikhail Sukhov PlazaSchemaParser предлагаю упрятать в PlazaTableSerializer Сделаю, когда устаканится модель метаданных. С тех пор как я написал PlazaSchemaParser, модель уже раза-три менялась, и я решил отложить доделку этого класса на самый конец.
|
|
Спасибо:
|
|
|
|
|
skuvv
|
Дата: 26.03.2011
|
|
|
|
Mikhail Sukhov skuvv aspirant skuvv К примеру я сравнил проект со своей старой программой plaza2, данные в текущий s# проект поступают медленнее на 6-10мс(время снимал с OnNewSecurityChanged к примеру).
Получается, ты делал свою реализацию PlazaTrader? Нет у меня не интерфейс как в s#, а напрямую работа c потоками и событиями Может выложить это ввиде отдельного теста для сравнения перфоманса? Насчет OnNewSecurityChanged - конечно. Если вместо поиска по словарю устраивать Exist Find и т.д., то я не удивлюсь и пол минутными задержками.[smile] Код void m_conn4_StreamDataInserted(CP2DataStream stream, String tableName, CP2Record rec) { try { if (stream.StreamName == streamFutCommonID) { int index = instruments.GetIndex(rec.GetValAsLong("isin_id")); if(index>=0) { double best_sell = Convert.ToDouble(rec.GetValAsVariant("best_sell")); double best_buy = Convert.ToDouble(rec.GetValAsVariant("best_buy")); if (best_buy != 0 && best_sell != 0) { instruments._bestask[index] = best_sell; instruments._bestask_vol[index] = rec.GetValAsLong("amount_sell"); instruments._bestbid[index] = best_buy; instruments._bestbid_vol[index] = rec.GetValAsLong("amount_buy"); instruments._lasttrade[index] = Convert.ToDouble(rec.GetValAsVariant("price")); instruments._lasttrade_vol[index] = rec.GetValAsLong("amount"); instruments._lasttrade_time[index] = Convert.ToDateTime(rec.GetValAsString("deal_time")); instruments._bidask_time[index] = DateTime.Now;
curr_rev_futcommon = rec.GetValAsLong("replRev");
log_buffer.Add(t4.Name, rec.GetValAsString("replID") + ";" + rec.GetValAsString("replRev") + ";" + instruments._isin_id[index] + ";" + instruments._bestask[index] + ";" + instruments._bestask_vol[index] + ";" + instruments._bestbid[index] + ";" + instruments._bestbid_vol[index] + ";" + instruments._lasttrade[index] + ";" + instruments._lasttrade_vol[index] + ";" + instruments._lasttrade_time[index].ToString(timefmt) + ";" + rec.GetValAsString("deal_count") + ";" + rec.GetValAsString("pos")); } } } } catch (Exception e) { log_buffer.Add("error", "[" + t4.Name + "] " + e.ToString()); } }
Event datainserted Все типы таблицы я получал в соответсвующих им win thread. Событий никаких нет [biggrin], заполняется статик массив instruments,а роботы на каждом прогоне его чекают. Ну и в конце запись в текстовики, через самописный логгер. ps фильтрация опять же массиву instruments
|
|
Спасибо:
|
|
|
|
|
Mikhail Sukhov
|
Дата: 27.03.2011
|
|
|
|
aspirant Mikhail Sukhov Сейчас PlazaListener создается в самом начале со всеми колонками. Как я уже писал, использовать надо только те колонки, что определены схемами PlazaTable.Columns. Как клиентский код создает таблицу с колонками и схемами? Твое видение с куском кода. Взял за основу отсюда: КодPlazaTableRegistry.FutCommon.Columns.Add(PlazaColumnRegistry.FuturesCommon.CurKotir);
PlazaTableRegistry.FutAggr5.Columns.Add(PlazaColumnRegistry.FuturesAggregation5.Moment); aspirant Mikhail Sukhov enum TableName лучше сделать статическим классом со строковыми константами. Я так понял, такие безобразные названия нужны лишь для того, чтобы ini файлы создавать? Если да, то по логике простой. Мы создаем текстовый файл, используем string. Вся логика в имени полей TableName - приведение в string... Так может тогда сразу сделать string? Этот enum был служебным, для внутреннего пользования. Клиенту его можно не показывать. Зачем я его сделал? Когда нужно набить пару десятков классов, enum + intellisense здорово помогает. Потом подстраховка от случайное опечатки в string. Сам я его не набивал: вместо этого пропарсил папку со всеми схемами. Ок, не поняли друг друга. Тогда ремарка и код. Если enum используется для задания строковых констант, то используется класс со строками: Кодstatic class TableName { public const string BaseContractsParams = "base_contracts_params"; .. }
public static PlazaTable FutAggr50 = new PlazaTable(TableName.BaseContractsParams, ReplicationStream.FutAggr50, "Фьючерсы: стакан глубиной 50 котировок"); На этом примере сразу видно недостаток именования перечислений (не ReplicationStreams, а ReplicationStream). Сходу кажется, что идет работа с потоком. А на самом деле к потокам это имеет о посредственное значение. aspirant Вообще PlazaTable сейчас и есть то, что ты предлагаешь. За исключением полей метаданных все остальные методы закомментены (причем, делал это не я). Можно сделать вот так: Код// вместо: public TableName SystemName { get; private set; } public string SystemName { get{ _systemName.ToString(); } Не понял, что за рокировка. aspirant Mikhail Sukhov Давайте подумаем насчет фильтрации. Сейчас это выглядит как то не очень. Я вообще собирался это делать внутри PlazaListener, но пока думал, skuvv успел привинтить свой фильтр[smile]. Что насчет методов RegisterSecurity/UnRegisterSecurity? С помощью них будем включать фильтрацию или они нужно для чего-то другого? Да, именно включение фильтра. Во всех АПИ (и я думаю в Плазе тоже рано или поздно сделают), фильтрация идет на серверной стороне и этот фильтра изменяется через методы, аналогичные Register Unregister.
|
|
Спасибо:
|
|
|
|
|
aspirant
|
Дата: 28.03.2011
|
|
|
|
Mikhail Sukhov КодPlazaTableRegistry.FutCommon.Columns.Add(PlazaColumnRegistry.FuturesCommon.CurKotir);
PlazaTableRegistry.FutAggr5.Columns.Add(PlazaColumnRegistry.FuturesAggregation5.Moment); Вопросы: - То есть мы исходим из того, что клиент подписывается на каждый поток только один раз? Напоминаю, у Плазы можно подписываться на один поток несколько раз. Клиенты не будут спрашивать? Когда проект будет зарелизен, изменить архитекутру будет сложно.
- Что делать с нашими стандартными потоками, которые нужны, чтобы мапить объекты. Мы договорились, что их скроем от клиента, чтобы гарантировать в них нужный набор колоннок. Придется все равно создавать какие-то отдельные таблицы.
Mikhail Sukhov Если enum используется для задания строковых констант, то используется класс со строками: Кодstatic class TableName... OK, сделаю после фильтрации. Сейчас все работает, а это рефакторинг функционала не добавит, только эстетику. Mikhail Sukhov Не понял, что за рокировка. Теперь она уже не нужна. Mikhail Sukhov На этом примере сразу видно недостаток именования перечислений (не ReplicationStreams, а ReplicationStream) Не знаю, дело вкуса. Я уже привык к единственному числу. Вот, кстати, MSDN'овский guideline.
|
|
Спасибо:
|
|
|
|
|
Mikhail Sukhov
|
Дата: 28.03.2011
aspirant Вопросы: - То есть мы исходим из того, что клиент подписывается на каждый поток только один раз? Напоминаю, у Плазы можно подписываться на один поток несколько раз. Клиенты не будут спрашивать? Когда проект будет зарелизен, изменить архитекутру будет сложно.
- Что делать с нашими стандартными потоками, которые нужны, чтобы мапить объекты. Мы договорились, что их скроем от клиента, чтобы гарантировать в них нужный набор колоннок. Придется все равно создавать какие-то отдельные таблицы.
1. Давай еще раз обсудим. С точки зрения практики - зачем это нужно? 2. Хм, а почему бы просто не оставить как есть сейчас?
|
|
Спасибо:
|
|
|
|