я должен стараться избегать "нового" ключевого слова в программном обеспечении "крайнее низкое время ожидания"?

Я пишу HFT торговое программное обеспечение. Я действительно забочусь о каждой микросекунде. Теперь написанный на C#, но я буду скоро мигрировать к C++.

Давайте рассмотрим такой код

// Original
class Foo {
....

   //method is called from one thread only so no need to be thread-safe
    public void FrequentlyCalledMethod() {
        var actions = new List();
        for (int i = 0; i < 10; i++) {
            actions.Add(new Action(....));
        }
       //use actions, synchronous
        executor.Execute(actions);
       //now actions can be deleted
    }

Я предполагаю, что сверхнизкое программное обеспечение времени ожидания не должно использовать "новое" ключевое слово слишком много, таким образом, я двинулся действия , чтобы быть областью:

// Version 1
class Foo {
....

    private List actions = new List();

   //method is called from one thread only so no need to be thread-safe
    public void FrequentlyCalledMethod() {
        actions.Clear()
        for (int i = 0; i < 10; i++) {
            actions.Add(new Action { type = ActionType.AddOrder; price = 100 + i; });
        }
       //use actions, synchronous
        executor.Execute(actions);
       //now actions can be deleted
    }

И вероятно я должен стараться избегать "нового" ключевого слова вообще? Я могу использовать некоторый "бассейн" предварительно ассигнованных объектов:

// Version 2
class Foo {
....

    private List actions = new List();
    private Action[] actionPool = new Action[10];

   //method is called from one thread only so no need to be thread-safe
    public void FrequentlyCalledMethod() {
        actions.Clear()
        for (int i = 0; i < 10; i++) {
            var action = actionsPool[i];
            action.type = ActionType.AddOrder;
            action.price = 100 + i;
            actions.Add(action);
        }
       //use actions, synchronous
        executor.Execute(actions);
       //now actions can be deleted
    }
  • , Как далеко я должен пойти?
  • , Как важный, чтобы избежать новый ?
  • я выиграю что-нибудь, в то время как использование предварительно ассигновало объект, который я только должен формировать? (тип набора и цена в примере выше)

Обратите внимание на то, что это - сверхнизкое время ожидания так, давайте предположим, что работа предпочтена против ремонтопригодности удобочитаемости и т.д. и т.д.

2
nl ja de
@delnan я действительно доверяю людям на stackoverflow:)
добавлено автор javapowered, источник
@MooingDuck благодарит так на C#, я, вероятно, должен просто использовать предварительно ассигнованные области, где возможный, но, когда мигрируется к C++ я могу заменить эти области повышением или другим распределителем.
добавлено автор javapowered, источник
@MooingDuck распределитель обычая будет быстрее, чем предварительно ассигнованная область?
добавлено автор javapowered, источник
@dmaij, когда я храню бассейн объектов как область метода isn' t I "хранения всего в памяти"? таким образом, моя "Версия 2" была бы самой быстрой?
добавлено автор javapowered, источник
@Chad меньше объектов, которые я ассигную динамично легкое заявление переписать к C++, наверное решая эту проблему, является одним из шагов, чтобы переписать применение к C++
добавлено автор javapowered, источник
Причина, почему та фрагментация памяти и поиск являются бассейном размер, который вы просили, становится медленнее на создании миллионов объектов. поэтому, необходимо использовать логику программы, чтобы предварительно структурировать память
добавлено автор im so confused, источник
Пожалуйста, don' t доверяют ТАК для такого рода вещи ха-ха, но в нашем финансовом приложении, we' ve по существу предварительно ассигновал огромные куски памяти, письменной таможенный "диспетчер памяти", и "ассигновал" наши новые объекты в этом космосе.
добавлено автор im so confused, источник
Следует иметь в виду, что в C#, ассигнующем новый объект, очень дешев. У GC есть указатель в памяти свободному разделу кучи, это перемещает указатель вверх размером какой you' распределение ре, и затем управляет конструкторами. It' s сборка мусора и дефрагментация, которая делает объекты кучи более дорогими, чем использование стековой памяти, но то время isn' t потраченный, когда объект ассигнуется, it' s потраченный позже. Если этот точный момент время очень чувствительный, но будет время простоя в какой-то момент в будущем (чтобы управлять коллекциями), то у вас не может быть проблемы. В C++ полная противоположность верна.
добавлено автор Servy, источник
Я удалил признак C++. Кроме комментария, что вы могли бы хотеть держать это в строевой стойке к C++ позже, вопрос не C++, связанный, и в данном случае не имеет никакого смысла пытаться ответить за оба языка, поскольку управление памятью очень отличается. Также обратите внимание, что <у кода>, нового , есть различные значения в C# в зависимости от особенностей типа (тип стоимости против ссылочного типа), и та информация отсутствует для Действие тип.
добавлено автор David Rodríguez - dribeas, источник
Если вы заботитесь о работе, сделайте или найдите таможенный объект-распределитель. У повышения и MSVC и есть многие и there' s еще много вокруг Интернета бесплатно.
добавлено автор Mooing Duck, источник
@javapowered: таможенный распределитель должен быть той же самой скоростью как предварительно ассигнованная область, кроме более легкого, чтобы использовать правильно, работы со стандартными контейнерами, и т.д., и т.д., и т.д.
добавлено автор Mooing Duck, источник
Перепишите свое заявление в C++, затем представьте его, затем попросите предложения.
добавлено автор Chad, источник
Выделение памяти может быть медленным, но это doesn' t должны быть.
добавлено автор Chad, источник
Если it' s настолько важный, кто вы собирающийся доверять: Люди в Интернете или научные оценки?
добавлено автор delnan, источник
Я соглашаюсь с AK4749, хранить все в памяти вместо распределения, вероятно, быстрее.
добавлено автор dmaij, источник
@javapowered, если бы вы могли бы сохранить все свои действия в памяти, вы только ассигновали бы их однажды. Действительно заботьтесь о том, как вы получаете доступ к ним, заказанный, крошивший, btree и т.д., так как это - ваш следующий вызов. Но, снова, попробуйте обоих, имейте размеры и посмотрите, который быстрее (академический подход). запрос ясного каждый раз также потеря производительности.
добавлено автор dmaij, источник
Я попробовал бы обоих и сделал бы измерения.
добавлено автор dmaij, источник

3 ответы

В C++ вы не должны новый , чтобы создать объект, у которого есть ограниченный объем.

void FrequentlyCalledMethod() 
{
    std::vector actions;
    actions.reserve( 10 );
    for (int i = 0; i < 10; i++) 
    {
        actions.push_back( Action(....) );
    }
   //use actions, synchronous
    executor.Execute(actions);
   //now actions can be deleted
}

Если , Действие является базовым классом и фактическими типами, которые вы имеете, будет иметь производный класс, вам будут нужны указатель или интеллектуальный указатель и , новый здесь. Но никакая потребность, если Действие - конкретный тип и все элементы, не будет иметь этот тип, и если этот тип конструируемый дефолтом, copyable и присваиваемый.

В целом, хотя, очень маловероятно, что ваши выигрыши в производительности прибудут из не использования нового. Это - просто хорошая практика здесь в C++, чтобы использовать местный объем функции, когда это - объем вашего объекта. Это вызвано тем, что в C++ необходимо проявить больше заботы об управлении ресурсами, и это сделано с техникой, известной как "RAII" - который по существу означает заботиться о том, как ресурс будет удален (через деструктор объекта) при распределении.

Высокая производительность, более вероятно, появится через:

  • надлежащее использование алгоритмов
  • надлежащие методы параллельной обработки и синхронизации
  • эффективное кэширование и отложенные вычисления.
4
добавлено
что вы подразумеваете "под эффективным кэшированием"? вы говорите о тайнике процессора? Я почти не использую параллельную обработку и синхронизацию. Я почти использую единственную нить для 80% работы, поскольку я хочу сделать работу меньше чем через 100 микросекунд и probaly намного меньше чем 100 микросекунд. это будет быстрее, чтобы использовать "конкретный тип", или использование "предварительно ассигновало объект, который только должен формироваться"?
добавлено автор javapowered, источник
и ваше собственное кэширование, и также гарантируя, чтобы некоторые операции гарантировали надлежащее кэширование процессора. We' у ve были темы прежде о различных размерах коллекции, дающих разительный контраст в скорости.
добавлено автор CashCow, источник
поместите его этот путь, если это оказывается новым использованием или не (на горячем коде), оказывает мало влияния на ваше выступление, тогда ваша программа слишком медленная.
добавлено автор user1252446, источник

Так, как я терпеть не могу HFT, я собираюсь сказать вам, как вытащить максимальную производительность из каждой нити на данном куске железа.

Here's an explanation of an example where a program as originally written was made 730 times faster.

Вы делаете это шаг за шагом. На каждой стадии вы находите что-то, что берет хороший процент времени, и вы фиксируете его. Ключевое слово , находят , в противоположность <им> предположение . Слишком много людей просто глазное яблоко, код, и фиксирует то, что они думают, поможет, и часто но не всегда это действительно помогает, некоторые. Это - догадки. Чтобы получить реальное ускорение, необходимо найти все проблемы, не просто некоторые можно предположить.

Если ваша программа делает новых , то возможности в какой-то момент, который будет тем, что необходимо зафиксировать. Но это не единственная вещь.

Вот теория позади него.

2
добавлено
я соглашаюсь, но это не ответ для моего вопроса. спасибо за связь it' s очень интересный.
добавлено автор javapowered, источник
@javapowered: Это говорит, что возможности новый , будет проблема, но не единственная. Одна из вещей, которые я делаю, объединить переработанные объекты.
добавлено автор Mike Dunlavey, источник

Для высокоэффективных торговых двигателей в хороших магазинах HFT, избегая new/malloc в коде C++ основное.

0
добавлено
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot