Ответ 1
Вы уже проделали большую часть работы. V8 не обеспечивает реализацию для setTimeout
, поскольку он не является частью ECMAScript. Функция, которую вы используете, реализована в timers.js, которая создает экземпляр объекта Timeout
, который является оберткой вокруг класса C.
В источнике есть комментарий, описывающий, как они управляют таймерами.
// Because often many sockets will have the same idle timeout we will not
// use one timeout watcher per item. It is too much overhead. Instead
// we'll use a single watcher for all sockets with the same timeout value
// and a linked list. This technique is described in the libev manual:
// http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#Be_smart_about_timeouts
Это указывает на использование двойного связанного списка, который является # 4 в связанной статье.
Если нет ни одного запроса, но много тысяч (миллионов...), все используя какой-то тайм-аут с одинаковым значением тайм-аута, затем один может сделать еще лучше:
При запуске таймаута вычислите значение тайм-аута и установите тайм-аут в конце списка.
Затем используйте ev_timer для запуска, когда тайм-аут в начале (например, с использованием техники № 3).
Когда есть активность, удалите таймер из списка, пересчитать таймаут, снова добавить его в конец списка и обязательно обновите ev_timer, если он был взят с начала список.
Таким образом, можно управлять неограниченным количеством таймаутов в O (1) раз для запуска, остановки и обновления таймеров за счет серьезное осложнение и необходимость использования постоянного таймаута. Постоянная timeout гарантирует, что список будет отсортирован.
Node.js спроектирован вокруг асинхронных операций, а setTimeout
является важной частью этого. Я бы не пытался запутаться, просто используйте то, что они предоставляют. Доверьтесь, что он достаточно быстро, пока вы не доказали, что в вашем конкретном случае это узкое место. Не зацикливайтесь на преждевременной оптимизации.
UPDATE
Что происходит, у вас есть по существу словарь тайм-аутов на верхнем уровне, поэтому все тайм-ауты в 100 мс группируются вместе. Когда добавляется новый тайм-аут или старшие триггеры таймаута, он добавляется к списку. Это означает, что самый старый тайм-аут, тот, который будет запускаться быстрее, находится в начале списка. Для этого списка есть один таймер, и он устанавливается на основе времени, пока первый элемент в списке не истечет.
Если вы вызываете setTimeout
1000 раз каждый с одинаковым значением таймаута, они будут добавлены в список в порядке, который вы назвали setTimeout
, и сортировка не требуется. Это очень эффективная настройка.