Анализ технологий обмена данных между процессами 

Mysql

~600 запись среднестатистического пакет данных игрока

PS Имеется возможность работы в асинхронном режиме (без ожидания записи чтения) благодаря расширениям от Swoole и др основанным на асинхрнном TCP взаимодействии


Redis

get set 13 000 (используется асинхронный запрос на получение в работе сервера)
pub sub 40 000  (в рамках работы сервера ничего не пишется, только на других сервисах)

PS Имеется возможность работы в асинхронном режиме, максимальный RPS ~100 000 согласно официальным тестам


ZeroMQ

pub sub 300 000 (в асинхронном, неблокируемом режиме согласно публичным тестам

RabbitMQ

до 60.000 согласно официальным данным, для текущего железа ожидалось бы ~6 000

Semaphores / System V (раздельная память с неблокируемым и блокируемым доступом)

pub sub 30 000 (ограничение по длине 16 000 байт)
get с блокировками 40 000
get без блокировки 2 000 000

Shmop (раздельная память данных между процессами, нужен алгоритм именования блоков памяти)

get 700 000

Libevent (событийная модель)

остановка основного кода, вызов функций по таймеру, продолжение основного кода. работает на базе тиков (ticks) процессора добавляя некую асинхронность встраиваясь в процессы
300 000 вызовов 

Swoole Timer (событийная модель)

...

Parallel (работа на разных ядрах CPU параллельно, обмен данных посредством каналов наподобии как в языке GO)

send (отправка данных на исполнение в отдельный поток)  1 600 000 запросов в секунду (без учета времени на чтение этих данных параллельным потоком)

Обычная переменная (для сравнения)

get 70 000 000

Opcache (кэшируемые данные в opcode)

get 50 000 000
- 30% скорости загрузки библиотек фреймворка при запуске процесса (в CLI не сильно актуально)

Анализ скорости работы стандартных функций базового языка на котором написан сервер - PHP

exec 30мс/вызов
pcntl_fork 1.2мс/вызов (только для поднятия сервера)
работы с mysql через php запись ~8мс (скачкообразно)
работа с mysql через php на запись асинхронно 1мс на непостоянных TCP (рассмотреть библиотеку Parallel , замерить скорости на отправку сообщений или использовать асинхронный TCP постоянного соединения)

Ниже среднее количество вызовов указанных функций в секунду (красным выделены текущие проблемные места):

microtime(true) 20 000 000
date("Y-m-d") 2 000 000
date("Y-m-d H:i:s") 1 000 000
localtime() 1 800 000
getdate() 1 100 000
(new \DateTime())->format("Y-m-d H:i:s:v") 700 000 
memory_get_usage() 70 000 000
asort 200 записей 100 000
get_object_vars 20 свойств 5 000 000
file_get_contents (он же fopen+fread ) 40 000
file_exists() 250 000
class_exists() 10 000 000 , на несуществующий  (полагаю проверяется наличие функций autoload ) 7 000 000
method_exists 20 000 000 на несуществующий (полагаю проверяется наличие в объекте метода __call) 11 000 000
$reflectionMethod = new ReflectionMethod(object $object, 'method_name') 8 000 000
$reflectionMethod->invoke()  10 000 000 (x4 быстрее если бы метод вызвался напрямую)
(new ReflectionMethod(...)) -> getParameters 40 000 000 (0 аргументов), далее: 10 000 000 (1 аргумент), 7 000 000 (2 аргумента)  и тп (в среднем на 1 аргумент падение скорости на 30% , +-5%)

new \ArrayIterator(...) - 500 000
implements \Iterator + его методы 1.000.000
array_intersect_key 5 000 000 (4 значения)
array_merge  5 000 000 (4 значения)
array_diff_key 10 000 000 (5 значений)
array_column 10.000.000 (1 значение, на 35% падение скорости за каждое доп значение)
ob_get_contents() + ob_clean() 10 000 000
ob_start() + ob_get_contents() +  ob_end_clean() 4 000 000

В тч. сравнительный анализ схожих по функционалу функций языка (одинаковые вводные)

json_encode() 1 800 000 vs serialize() 1 700 000
json_decode(... , true) 600 000 vs unserialize 700 000 (рассмотреть библиотеку Simdjson)
восстановление Объекта из строки new A( ... explode(',', $a)) 3 800 000
SeasLog::log 80 000 vs file_put_contents (..., date("Y-m-d H:i:s").'|'.getmypid().' ....') 5000 vs fopen('..', 'a') + fwrite 80 000 (используется для логов. принято решение писать логи через множественные TCP соединения асинхронно но с потерей порядка записи)



Что нового?


Статьи про разработку продукта

Intro Image

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

В статье я расскажу как разработчиков вводят в заблуждение рассказывая что необходимо учесть в первую очередь при разработке серверов (и не только для игр), но умалчивая о реальных "узких местах" (проблемах).

В конце статьи будет приложена видео версия.

Читать далее

Кабинет

Игры