Was ich mir nicht erklären kann:
Warum ist der getter-Zugriff des Interfaces (var 1) um Faktor 2 langsamer als die Indexberechung per function (var 2)?
Direkter Funktionsaufruf vs. indirekter Funktionsaufruf. Bei deinem Funktionsaufruf generiert der Compiler eine CALL-Instruktion zu einer bekannten Adresse. Beim Interface hingegen weiß der Compiler zur Compile-Zeit noch nicht, welche Implementierung sich dahinter zur Laufzeit verbergen wird. Deshalb besteht der Funktionsaufruf zur Laufzeit aus zwei Teilen: Zuerst wird der Funktionspointer aus dem Interface ausgelesen und im zweiten Schritt wird er dann angesprungen.
In Assember-Form sieht das ungefähr so aus:
Variante 1
Code:
MOV EAX, [interface.getval] // Funktionsadresse ins Register EAX laden
CALL EAX // Springe zur Adresse im Register EAX
Variante 2
Möglich, dass der echte Assember-Code etwas anders aussieht, aber das Prinzip sollte klar werden.