Ответ 1
Скомпилированные языки часто имеют быстрый метод отправки, потому что вызывающий код знает индекс в классе vtable, который представляет собой массив указателей на методы. После нескольких разыменований указателей вызывающий код может перейти прямо в этот метод. Компилятор создает vtable и заменяет каждое имя метода в исходном коде числовым индексом метода в таблице vtable.
Динамические языки, такие как Ruby, часто имеют медленную отправку методов, потому что вызывающий код имеет имя для метода, а не указатель (или индекс в массив, содержащий указатели). Вызывающий код должен запросить объект для своего класса, затем должен спросить класс, есть ли у него метод с этим именем, а если нет, перейдите в цепочку предков, спрашивающих каждого предка, если у него есть метод с таким именем ( это то, что делает компилятор на скомпилированном языке, поэтому компиляция выполняется медленно и отправка метода выполняется быстро). Вместо нескольких указаний на указатели, требующих всего нескольких машинных инструкций для вызова метода, динамический язык должен выполнять от десятков до сотен машинных инструкций для поиска класса объекта и всех классов-предков объекта для этого метода. Каждый класс имеет HashTable имен → методы, но HashTables со строковыми ключами на порядок медленнее, чем массивы с целыми индексами.
Есть способы оптимизировать отправку методов в динамических langauges, конечно. В Ruby работает то, над чем работают JRuby, Rubinius и IronRuby. Но это тема для другого вопроса.