Я бы сказал, что ты наполовину прав. Если вы изобразите скорость интерпретации с уровнем языка по оси X и скоростью выполнения по оси Y, вы получите кривую «ванны» - интерпретация языка очень низкого уровня может быть довольно быстрой, а интерпретация чрезвычайно высокой Уровень языка может быть довольно быстрым. Между ними интерпретация существенно медленнее.
Учитывая язык ввода очень высокого уровня (например, APL), вы получаете минимальные издержки на интерпретацию, потому что вы можете выполнять большую работу, основанную на анализе относительно небольшого количества входного кода.
С другой стороны, вы можете получить довольно приличную скорость просто потому, что при достаточно низкоуровневом языке интерпретация становится почти тривиальной. Внутренний интерпретатор реализации Forth является ярким примером этого. Они часто представляют конкретную программу достаточно компактно, что, как правило, весьма удобно для кэширования, поэтому, по крайней мере, теоретически вы можете получить выполнение так же быстро (или даже несколько быстрее), как чистый машинный код.
Первоначально предполагалось, что большинство JVM, «управляемая» среда .NET, интерпретаторы байт-кода Smalltalk и т. Д. Будут соответствовать последнему случаю. Как быстро обнаружили большинство тех, кто пытался разработать их, сложно поддерживать затраты на интерпретацию на достаточно низком уровне для достижения этой цели. У каждого, кого я знаю о том, что он вписывается в этот класс, есть внутренний цикл, написанный на ассемблере вручную и обычно хорошим программистом на ассемблере. Я бы даже сказал, что если вы попытаетесь использовать язык более высокого уровня (даже C), он будет медленнее и, вероятно, значительно (если вы добавляете накладные расходы для каждые инструкция ввода, даже одна дополнительная инструкция во внутреннем цикле почти наверняка приведет к измеримому снижению скорости).