Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Торговый форум, автоматические торговые системы и тестирование торговых стратегий
Библиотеки: JSON библиотека для LLM
fxsaber, 2026.02.19 21:56
Предполагаю, что в MQL5, из-за принудительной проверки на выход за границы массива, это условие будет выполняться медленнее, чем следующее.
Чувак, это фантастические предложения. Я очень ценю, что вы нашли время покопаться в исходном коде и указать, где мы могли бы выжать больше производительности.
Ты был абсолютно прав насчет накладных расходов на проверку границ массива в MQL5. Несмотря на то, что g_cc работает быстро, проверки компилятора на безопасность увеличиваются в узком цикле. Я отказался от поиска цифр в таблице и реализовал вашу побитовую проверку ALU (c ^ '0') <= 9 . Это чище и определенно быстрее.
Я также последовал вашему совету по поводу разбора чисел и переписал его, сделав однопроходным. Теперь он потребляет цифры непосредственно в аккумулятор и переключается на плавающую логику только при попадании на десятичную точку или экспоненту. Больше никакого двойного сканирования.
Кроме того, я изменил порядок ветвей главного цикла, отдав приоритет строкам ( " ) и числам, что должно помочь в предсказании ветвей процессора, поскольку это самые распространенные лексемы.
Еще раз спасибо за помощь. Библиотека стала значительно лучше благодаря вашему вкладу!
🔗 v3.5.0 уже в продаже: GitHub/Forge
Hi Jonathan,
Thanks for the great library.
While integrating it with Binance WebSocket streams I ran into two bugs. Both reproduce on the current public version. Test script and output at the end of the post.
(При интеграции с Binance WebSocket streams я столкнулся с двумя багами.)
Bug #1 — true and false produce identical tape entries
(Баг #1 — true и false создают одинаковые записи в tape)
In the parser, the branches for 't' and 'f' literals write the same payload bit:
(В парсере ветки для литералов 't' и 'f' записывают одинаковый бит payload:)
GetBool() already reads bit 0 correctly ( tape[idx] & 1 ), so this is just a one-character typo in the parser:
(GetBool() уже правильно читает бит 0, поэтому это просто опечатка в одну букву в парсере:)
After this fix ToBool() returns the correct value for both true and false .
(После исправления ToBool() возвращает правильное значение и для true, и для false.)
Bug #2 — ToString() reads adjacent tape slots on non-string nodes
CJsonNode::ToString() has no type check:
Баг #2 — ToString() читает соседние слоты tape для не-строковых узлов
CJsonNode::ToString() не проверяет тип:
GetStr() blindly interprets tape[idx + 1] as a packed (offset, length) pair:
GetStr() слепо интерпретирует tape[idx + 1] как пару (offset, length):
For non-string nodes this reads a tape slot that does not belong to the current node. The most visible manifestation is on integer nodes, where tape[idx + 1] holds the integer value itself. For {"v":42} calling r["v"].ToString() returns the entire input buffer (8 bytes) — because the payload 42 happens to decode as (offset=0, length=8) .
With larger integers or different offsets the same path can return arbitrary memory contents from the input buffer, potentially out of bounds.
Suggested fix — match the convention used by ToInt() :
Для не-строковых узлов это читает слот tape, который не принадлежит текущему узлу. Самое заметное проявление — на целочисленных узлах, где tape[idx + 1] хранит само значение integer. Для {"v":42} вызов r["v"].ToString() возвращает весь входной буфер (8 байт) — потому что payload 42 случайно декодируется как (offset=0, length=8). С большими целыми числами или другими смещениями этот же путь может возвращать произвольное содержимое входного буфера, потенциально за его пределами. Предлагаемое исправление — следовать соглашению, используемому в ToInt().
Or a richer version that returns a string representation of any scalar type (depends on Bug #1 being fixed first):
Или более полная версия, которая возвращает строковое представление любого скалярного типа (зависит от предварительного исправления Bug #1):
Reproduction
Output on the current version:
Note Cases D and E: ToString() on an int-valued node returned the entire raw input buffer, because the int's payload decoded as offset=0, length=(buffer size) . Length scales linearly with input — confirming an out-of-node read, not just a stale memory artifact.
(Примечание по случаям D и E: ToString() на узле с int вернул весь исходный входной буфер, так как payload 42 декодировался как (offset=0, length=размер буфера). Длина растёт линейно с размером входных данных — это подтверждает чтение за пределами узла, а не просто артефакт памяти.)
Happy to test a patch if you want to validate the fix before publishing.
Thanks for the work on this library!
Спасибо всем за участие.
@fxsaber - Проанализировал оба файла. Шаблон XOR-first, применяемый последовательно во всем конвейере разбора чисел (каждый байт XOR'ится ровно один раз, все сравнения в преобразованной области), был включен в v3.6.0 и доработан в v3.7.0. Хирургический вклад, как всегда. Спасибо.
@Sunriser - Обе ошибки подтверждены и исправлены в v3.7.0:
Вv3.7.0 также добавлены: ParseBuffer(uchar &data[], int data_len) для прямого разбора буфера без StringToCharArray , SWAR Unescape, длина ключа хранится в ленте (исключает сканирование для цитирования при сериализации), прямая запись байтов в сериализатор, ArrayResize с запасом и HexToDec через таблицу поиска.
Обратная совместимость. Ноль ломающих изменений.
Примечание: версия 3.6.0 (с расширенными таблицами Pow10, сериализацией по парам цифр и 4-кратным развёрнутым хэшем) была готова уже давно - я просто забыл её выложить. 😅
Спасибо за отзывы - библиотека развивается благодаря подобным вкладам.