Статьи

C ++ или Java, что быстрее для высокочастотной торговли?

обзор

Существуют противоречивые мнения о том, что является лучшим решением для высокочастотной торговли. Часть проблемы заключается в том, что то, что торгует на высокой частоте, меняется больше, чем вы могли ожидать, другая часть — это то, что подразумевается под более быстрым.

Мой взгляд

Если у вас есть типичный Java-программист и типичный C ++ программист, каждый из которых имеет несколько лет опыта написания типичной объектно-ориентированной программы, и вы даете им такое же количество времени, Java-программист, скорее всего, будет иметь работающую программу раньше и будет иметь больше время настроить приложение. В этой ситуации, скорее всего, Java-приложение будет работать быстрее. ИМХО.

По моему опыту, Java лучше работает на C ++ при обнаружении кода, который не нужно делать. esp микро-тесты, которые не делают ничего полезного. ? Если вы настроите Java и C ++ настолько далеко, насколько это возможно, учитывая любой опыт и время, программа на C ++ будет работать быстрее. Однако, учитывая ограниченные ресурсы и изменяющуюся среду, динамический язык не будет работать. то есть в реальных приложениях.

В латентности космического пространства вам нужно, чтобы задержки составляли менее 10 единиц, чтобы быть очень высокой частотой. Java и даже стандартный OOP C ++ на стандартном оборудовании не подходят. Вам нужна C или урезанная версия C ++ и специальное оборудование, такое как FPGA, GPU.

В FX высокая частота означает задержку менее 100 мкс. В этом пространстве C ++ или урезанная Java (low GC) с сетевым адаптером обхода ядра являются опцией. В этом пространстве использование того или иного языка будет иметь свои плюсы и минусы. Лично я считаю, что Java обеспечивает большую гибкость, поскольку биржи постоянно меняются, если вы полагаете, что можете использовать ИТ для достижения конкурентного преимущества.

Во многих случаях, когда люди говорят о высокой частоте, особенно о Банках, они говорят, что меньше 1 мс или однозначная мс. В этом пространстве я бы сказал, что гибкость / динамическое программирование Java, Scala или C # и т. Д. Даст вам время для выхода на рынок, удобства обслуживания и надежности по сравнению с C / C ++ или FPGA.


Проблема, с которой сталкивается Java

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

Проблема не в GC или Java, поскольку ни одна из них не играет большую роль. Проблема в том, что часть кэша была выгружена, а сама копия занимает больше времени. Это то же самое для любой операции, которая обращается к памяти. например, доступ к простым объектам также будет медленнее.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
private void doTest(Pauser delay) throws InterruptedException {
    int[] times = new int[1000 * 1000];
    byte[] bytes = new byte[32* 1024];
    byte[] bytes2 = new byte[32 * 1024];
    long end = System.nanoTime() + (long) 5e9;
    int i;
    for (i = 0; i < times.length; i++) {
        long start = System.nanoTime();
        System.arraycopy(bytes, 0, bytes2, 0, bytes.length);
        long time = System.nanoTime() - start;
        times[i] = (int) time;
        delay.pause();
        if (start > end) break;
    }
    Arrays.sort(times, 0, i);
    System.out.printf(delay + ": Copy memory latency 1/50/99%%tile %.1f/%.1f/%.1f us%n",
            times[i / 100] / 1e3,
            times[i / 2] / 1e3,
            times[i - i / 100 - 1] / 1e3
    );
}

Тест делает одно и то же много раз, с разными задержками между выполнением этого теста. Тест проводит большую часть своего времени в нативных методах, и никакие объекты не создаются и не удаляются, как во время теста.

Выход: Копирование задержки памяти 1/50/99% плитки 1.6 / 1.6 / 2.3 us
NO_WAIT: копирование задержки памяти 1/50/99% плитки 1.6 / 1.6 / 1.6 us
BUSY_WAIT_10: задержка копирования памяти 1/50/99% плитки 3.1 / 3.5 / 4.4 us
BUSY_WAIT_3: Копирование задержки памяти 1/50/99% плитки 2.7 / 3.0 / 4.0 us
BUSY_WAIT_1: задержка копирования памяти 1/50/99% плитки 1.6 / 1.6 / 2.6 us
SLEEP_10: копирование памяти задержка 1/50/99% плитки 2.3 / 3.7 / 5.2 us
SLEEP_3: копирование задержки памяти 1/50/99% плитки 2.7 / 4.4 / 4.8 us
SLEEP_1: копирование памяти задержка 1/50/99% плитки 2.8 / 4.6 / 5.0 us

Типичное время (среднее значение), необходимое для выполнения копирования в память, варьируется от 1,6 до 4,6 мкс в зависимости от того, было ли занятое ожидание или режим ожидания в течение от 1 до 10 мс. Это соотношение примерно в 3 раза, которое не имеет ничего общего с Java, но не имеет никакого реального контроля. Даже лучшие времена меняются примерно в 2 раза.


Код

ThreadlatencyTest.java


Вывод

На сверхвысокой частоте ядро ​​ядра будет больше C, сборки и специального оборудования, чем OOP C ++ или Java. На рынках, где требования к задержке движка менее строгие, C ++ и Low GC Java становятся опцией. Поскольку требования к задержке становятся менее строгими, Java и другие динамические языки могут быть более продуктивными. В этой ситуации Java быстрее выходит на рынок, поэтому вы можете воспользоваться изменениями рынка / требований.

Справка: C ++ или Java, что быстрее для высокочастотной торговли? от нашего партнера JCG Питера Лори в Vanilla Java .

Статьи по Теме: