Заметные улучшения производительности были выполнены с использованием нижеперечисленных техник. Еще многое предстоит сделать, см. на странице Производительность текущие вопросы и размышления.
Нативные вычисления
[реализовано]Когда я последний раз профилировал код I2P, большая часть времени тратилась на одну функцию: java.math.BigInteger modPow. Вместо того чтобы попытаться оптимизировать этот метод, мы будем вызывать GNU MP - безумно быструю математическую библиотеку (с отлаженным ассемблером под множество архитектур). (Редактор: смотри NativeBigInteger для быстрого шифрования публичным ключом)
ugha и duck работают над связующим кодом C/JNI, и существующий код Java уже внедрен соответствующими ловушками, как только он был готов. Предварительные результаты выглядят потрясающе - запуск маршрутизатора с нативным GMP modPow дает около 800% прироста производительности шифрования и снижает нагрузку наполовину. Это было проверено только на одном компьютере пользователя и оно уже готово для внедрения.
Чесночная упаковка "ответа" LeaseSet
[реализовано, но нуждается в настройке]Этот алгоритмический прием может быть применим только к тем приложениям, которые хотят получать ответ от своих узлов (хотя он включает в себя все, что использует I2PTunnel или ministreaming библиотеку mihi):
Ранее, когда Alice отправила сообщение Bob'у, когда Bob отвечал, он был вынужден выполнить поиск в сетевой базе данных - отправляя несколько запросов, чтобы добраться до текущего LeaseSet Alice. Если у него уже есть текущий LeaseSet Alice, он может вместо этого сразу отправить свой ответ - из-за этого (частично) вы обычно тратите немного больше времени для обращения к кому-то в первый раз, но последующие обращения проходят быстрее. Сейчас - для всех клиентов - мы упаковываем текущий LeaseSet отправителя в garlic, который доставляется получателю, и когда он соберется ответить, у него всегда будет локально хранимый LeaseSet - это полностью исключает необходимость поиска по сетевой базе данных при ответах. Это сохраняет большую часть пропускной полосы отправителя для такого быстрого ответа. Если мы делаем это не очень часто, общее использование пропускной полосы сети может уменьшиться, т.к. получателю не нужно выполнять поиск по сетевой базе данных.
Для неопубликованных LeaseSets, таких как "shared clients", есть только один способ доставить LeaseSets Бобу. К сожалению, это связывание каждый раз добавляет почти 100% накладных расходов на высокоскоростное соединение и гораздо больше для соединений с меньшими сообщениями.
Изменения, запланированные в релизе 0.6.2, будут отправлять LeaseSet только при необходимости, в начале соединения или когда изменится LeaseSet. Это значительно уменьшит общие накладные расходы системы сообщений I2P.
Более эффективное отклонение TCP запросов
[реализовано]В настоящий момент, все соединения TCP выполняют проверку валидности узла после выполнения полного (дорогого) алгоритма Диффи-Хеллмана обмена приватными ключами сессии. Это означает, что если чьи-то часы сильно неточны, или его NAT/firewall/и т.д. неверно сконфигурирован (или используется несовместимая версия роутера), эти клиенты постоянно (не совсем постоянно, благодаря бан-листам) провоцируют бесполезные ресурсоемкие криптографические операции на всех известных им узлах. Хотя мы и хотим оставить некоторые проверки внутри границ шифрования, мы также хотим обновить протокол так, чтобы некоторые проверки выполнялись раньше и мы могли отбросить невалидные соединения, не тратя процессорное время и другие ресурсы.
Регулировка проверки туннеля
[реализовано]Вместо использования теперешней довольно случайной схемы, мы должны использовать более контекстный алгоритм для проверки туннелей, т.к., если мы уже знаем, что он передает данные корректно, то нет необходимости проверять его, и, если мы давно не получали из него данных, возможно, стоит воспользоваться им для отправки. Это уменьшит конкуренцию туннелей из-за избытка сообщений, а также улучшит скорость, с которой мы определяем - и фиксируем - ошибочные туннели.
Постоянный Туннель / Выбор Срока Аренды
Выбор исходящего туннеля реализован в 0.6.1.30, выбор срока аренды входящего реализован в релизе 0.6.2.
Случайный выбор туннелей и сроков аренды для каждого сообщения создает большое количество случаев доставки не-по-очереди, что мешает потоковой библиотеке увеличивать размер ее окна до максимума. При сохранении выбора для одного соединения скорость передачи намного больше.
Сжатие некоторых структур данных
[реализовано]Сообщения I2NP и их содержимое уже определены и имеют довольно компактную структуру, хотя один атрибут структуры RouterInfo не "настраиваемый" - это соответствие имя = значение в виде ASCII. Сейчас мы заполняем ее публичной статистикой - около 3300 байт на узел. Простое применение сжатия GZip позволит сократить ее размер до 1/3, и когда вы поймете, как часто структуры RouterInfo передаются по сети, вы увидите, что это будет значительным выигрышем - каждый раз, когда маршрутизатор запрашивает у другого содержимое сетевой БД, которого нет у узла, он получает 3-10 записей RouterInfo.
Обновление протокола ministreaming
[заменен на полностью потоковый протокол]Сейчас у библиотеки мини-потоков mihi есть довольно простой потоковый протокол согласования - Alice отправляет Бобу сообщение SYN, Боб отвечает сообщением ACK, затем Alice и Боб обмениваются данными до тех пор пока один из них не отправит другому сообщение CLOSE. Для длительных подключений (например, для IRC-сервера), эти издержки незначительны, но для некоторых простых ситуаций запрос-ответ (например, запрос/ответ HTTP) приходится отправлять вдвое больше сообщений, чем это необходимо. Если, тем не менее, Alice комбинирует свою отправку с сообщением SYN, и Боб комбинирует его первый ответ с ACK - и, возможно, также включит флаг CLOSE - временные потоки, такие как запросы HTTP, могут быть сокращены до пары сообщений, вместо SYN+ACK+запрос+ответ+CLOSE.
Реализация полностью потокового протокола
[реализовано]Протокол мини-потоков унаследовал преимущества плохого проектного решения клиентского протокола I2P (I2CP) - иллюстрация "mode=GUARANTEED", позволяющая то, что иначе было бы ненадежным, негарантированным, протокол на основе сообщений используется для надежной, блокирующей операции (приоткрывая покров, оно все равно остается ненадежным и основанным на сообщениях с гарантиями доставки, предоставляемыми маршрутизатором с помощью чесночной маршрутизации данных с сообщением "ACK" внутри, так что когда данные доходят до получателя, сообщение ACK отправляется обратно к нам [через туннели, естественно]).
Как я уже сказал, наличие I2PTunnel (и библиотеки мини-потоков) было наилучшим путем из всех возможных, но уже доступны и более эффективные механизмы. Когда мы выпиливаем функциональность "mode=GUARANTEED", мы в сущности оставляем себе I2CP, который выглядит как анонимный уровень IP, и, т.о., мы сможем реализовать в потоковой библиотеке преимущества архитектурного опыта слоя TCP - селективные ACK, обнаружение коллизий, nagle и т.д.