Updated measurements:
Updated results for running on .NET 5.0 and with added FastExpressionCompiler library (.CompileFast() rows):
| R | 
Call | 
Invocation type | 
ms | 
| 1 | 
Virtual | 
IFoo.Bar() | 
434 | 
| 1 | 
Direct | 
Foo.Bar() | 
324 | 
| 4-6 | 
Virtual | 
(iFooArg) => iFooArg.Bar() | 
597 | 
| 4-6 | 
Direct | 
(fooArg)  => fooArg.Bar() | 
487 | 
| 4-6 | 
Virtual | 
() => IFoo.Bar() | 
596 | 
| 4-6 | 
Direct | 
() => FooImpl.Bar() | 
487 | 
| 2-3 | 
Virtual | 
Manual Func<IFoo, int>    Expression + .Compile() | 
595 | 
| 2-3 | 
Direct | 
Manual Func<FooImpl, int> Expression + .Compile() | 
433 | 
| 2-3 | 
Virtual | 
CSharpScript.Eval. Func<IFoo, int> expr    + .Compile() | 
594 | 
| 2-3 | 
Direct | 
CSharpScript.Eval. Func<FooImpl, int> expr + .Compile() | 
433 | 
| 9 | 
Virtual | 
Manual Func<int> Expression + .Compile() | 
866 | 
| 9 | 
Direct | 
Manual Func<int> Expression + .Compile() | 
542 | 
| 4-6 | 
Virtual | 
Manual Func<IFoo, int>    Expression + .CompileFast() | 
596 | 
| 4-6 | 
Direct | 
Manual Func<FooImpl, int> Expression + .CompileFast() | 
485 | 
| 7-8 | 
Virtual | 
CSharpScript.Eval. Func<IFoo, int> expr    + .CompileFast() | 
649 | 
| 7-8 | 
Direct | 
CSharpScript.Eval. Func<FooImpl, int> expr + .CompileFast() | 
486 | 
| 7-8 | 
Virtual | 
Manual Func<int> Expression + .CompileFast() | 
650 | 
| 7-8 | 
Direct | 
Manual Func<int> Expression + .CompileFast() | 
486 | 
| 10 | 
Virtual | 
CSharpScript.Eval. Func<IFoo, int> to lambda | 
810 | 
| 10 | 
Direct | 
CSharpScript.Eval. Func<FooImpl, int> to lambda | 
758 | 
| 99 | 
Virtual | 
MethodInfo.Invoke(FooImpl, Bar) | 
38529 | 
| 99 | 
Direct | 
MethodInfo.Invoke(IFoo, Bar) | 
19380 | 
 
Rows are grouped by invocation types, ranked by total time of direct-call variant (and by virtual-call is special cases).
Note that:
- pre-compiled direct-call lambdas seem to have no performance difference w.r.t. way of accessing the instance reference (from closure / from argument); since the instance likely isn't accessed at all in the resulting assembly (it is not needed), it makes sense.
 
Expression.Compile with hand-written expression is faster then pre-compiled lambda, but only when instance reference is passed as argument! When the instance reference is stored as a constant (simulating closure), it is slower then pre-compiled lambdas! 
- Using 
CSharpScript.EvaluateAsync to generate the expression of instance-ref-by-argument-call and then compiling with Expression.Compile is comparable to writing the expression by hand (and compiling it). Performance might vary with library/compiler version! 
- Using 
CSharpScript.EvaluateAsync to generate a lambda directly is slower then generating an expression and then compiling with Expression.Compile 
- time it takes to actually compile the expressions/script to lambdas is not benchmarked
 
Original:
I sligthly modified the code of @Serge Semenov and ran it on .NET Core 3.1 - it seems the performance of Expression.Compile() has changed dramatically.
I have also added code that uses CSharpScript to compile lambdas from string. Note that .CompileToMethod is not available in .NET Core.
| R | 
Call | 
Invocation type | 
ms | 
| 1 | 
Virtual | 
IFoo.Bar() | 
431 | 
| 1 | 
Direct | 
Foo.Bar() | 
319 | 
| 4 | 
Virtual | 
(iFooArg) => iFooArg.Bar() | 
622 | 
| 4 | 
Direct | 
(fooArg)  => fooArg.Bar() | 
478 | 
| 5 | 
Virtual | 
() => IFoo.Bar() | 
640 | 
| 5 | 
Direct | 
() => FooImpl.Bar() | 
477 | 
| 2 | 
Virtual | 
Manual Func<IFoo, int>    Expression + .Compile() | 
531 | 
| 2 | 
Direct | 
Manual Func<FooImpl, int> Expression + .Compile() | 
426 | 
| 3 | 
Virtual | 
CSharpScript.Eval. Func<IFoo, int> expr    + Expression.Compile() | 
586 | 
| 3 | 
Direct | 
CSharpScript.Eval. Func<FooImpl, int> expr + Expression.Compile() | 
423 | 
| 6 | 
Virtual | 
Manual Func<int> Expression + .Compile() | 
908 | 
| 6 | 
Direct | 
Manual Func<int> Expression + .Compile() | 
584 | 
| 7 | 
Virtual | 
CSharpScript.Eval. Func<IFoo, int> to lambda | 
799 | 
| 7 | 
Direct | 
CSharpScript.Eval. Func<FooImpl, int> to lambda | 
748 | 
| 99 | 
Virtual | 
MethodInfo.Invoke(FooImpl, Bar) | 
43533 | 
| 99 | 
Direct | 
MethodInfo.Invoke(IFoo, Bar) | 
29012 | 
 
Rows are grouped by invocation types, ranked by total time of direct-call variant (and by virtual-call variant is difference is not significant enough).
Code:
//#define NET_FW    //if you run this on .NET Framework and not .NET Core or .NET (5+)
//uses:
// FastExpressionCompiler 3.3.4
// Microsoft.CodeAnalysis.CSharp.Scripting
using System;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using FastExpressionCompiler;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
namespace ExpressionTest
{
   public interface IFoo
   {
      int Bar();
   }
   public sealed class FooImpl : IFoo
   {
      [MethodImpl(MethodImplOptions.NoInlining)]
      public int Bar()
      {
         return 0;
      }
   }
   class Program
   {
      static void Main(string[] args)
      {
         var foo = new FooImpl();
         var iFoo = (IFoo)foo;
         Func<int> directLambda = () => foo.Bar();
         Func<int> virtualLambda = () => iFoo.Bar();
         Func<FooImpl, int> directArgLambda = fooArg => fooArg.Bar();
         Func<IFoo, int> virtualArgLambda = iFooArg => iFooArg.Bar();
         var compiledArgDirectCall = CompileBar<FooImpl>();
         var compiledArgVirtualCall = CompileBar<IFoo>();
         var compiledArgFromScriptDirectCall = CompileBarFromExprFromScript<FooImpl>();
         var compiledArgFromScriptVirtualCall = CompileBarFromExprFromScript<IFoo>();
         var compiledDirectCall = CompileBar(foo, asInterfaceCall: false);
         var compiledVirtualCall = CompileBar(foo, asInterfaceCall: true);
         var compiledFastArgDirectCall = CompileFastBar<FooImpl>();
         var compiledFastArgVirtualCall = CompileFastBar<IFoo>();
         var compiledFastArgFromScriptDirectCall = CompileFastBarFromExprFromScript<FooImpl>();
         var compiledFastArgFromScriptVirtualCall = CompileFastBarFromExprFromScript<IFoo>();
         var compiledFastDirectCall = CompileFastBar(foo, asInterfaceCall: false);
         var compiledFastVirtualCall = CompileFastBar(foo, asInterfaceCall: true);
         var barMethodInfo = typeof(FooImpl).GetMethod(nameof(FooImpl.Bar));
         var iBarMethodInfo = typeof(IFoo).GetMethod(nameof(IFoo.Bar));
#if NET_FW
         var compiledToModuleDirect = CompileToModule<FooImpl>();
         var compiledToModuleVirtual = CompileToModule<IFoo>();
#endif
         var compiledViaScriptDirect = CompileViaScript<FooImpl>();
         var compiledViaScriptVirtual = CompileViaScript<IFoo>();
         var iterationCount = 0;
         int round = 0;
         start:
         if (round == 0)
         {
            iterationCount = 2000000;
            Console.WriteLine($"Burn in");
            Console.WriteLine($"Iteration count: {iterationCount:N0}");
            goto doWork;
         }
         if (round == 1)
         {
            Task.Delay(5000).Wait();
            iterationCount = 200000000;
            Console.WriteLine($"Iteration count: {iterationCount:N0}");
            goto doWork;
         }
         return;
         doWork:
         {
            Stopwatch sw;
            long elapsedMs;
            sw = Stopwatch.StartNew();
            Console.WriteLine($"Call | Invocation type | ms");
            Console.WriteLine($"-----|-----------------|--:");
            for (int i = 0; i < iterationCount; i++)
               iFoo.Bar();
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               iFoo.Bar();
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `IFoo.Bar()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               foo.Bar();
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               foo.Bar();
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `Foo.Bar()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               virtualArgLambda(iFoo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               virtualArgLambda(iFoo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `(iFooArg) => iFooArg.Bar()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               directArgLambda(foo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               directArgLambda(foo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `(fooArg)  => fooArg.Bar()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               virtualLambda();
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               virtualLambda();
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `() => IFoo.Bar()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               directLambda();
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               directLambda();
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `() => FooImpl.Bar()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledArgVirtualCall(iFoo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledArgVirtualCall(iFoo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `Manual Func<IFoo, int>    Expression + .Compile()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledArgDirectCall(foo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledArgDirectCall(foo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `Manual Func<FooImpl, int> Expression + .Compile()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledArgFromScriptVirtualCall(iFoo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledArgFromScriptVirtualCall(iFoo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `CSharpScript.Eval. Func<IFoo, int> expr    + .Compile()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledArgFromScriptDirectCall(foo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledArgFromScriptDirectCall(foo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `CSharpScript.Eval. Func<FooImpl, int> expr + .Compile()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledVirtualCall();
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledVirtualCall();
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `Manual Func<int> Expression + .Compile()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledDirectCall();
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledDirectCall();
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `Manual Func<int> Expression + .Compile()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledFastArgVirtualCall(iFoo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledFastArgVirtualCall(iFoo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `Manual Func<IFoo, int>    Expression + .CompileFast()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledFastArgDirectCall(foo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledFastArgDirectCall(foo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `Manual Func<FooImpl, int> Expression + .CompileFast()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledFastArgFromScriptVirtualCall(iFoo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledFastArgFromScriptVirtualCall(iFoo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `CSharpScript.Eval. Func<IFoo, int> expr    + .CompileFast()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledFastArgFromScriptDirectCall(foo);
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledFastArgFromScriptDirectCall(foo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `CSharpScript.Eval. Func<FooImpl, int> expr + .CompileFast()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledFastVirtualCall();
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledFastVirtualCall();
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `Manual Func<int> Expression + .CompileFast()` | {elapsedMs}");
            for (int i = 0; i < iterationCount; i++)
               compiledFastDirectCall();
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledFastDirectCall();
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `Manual Func<int> Expression + .CompileFast()` | {elapsedMs}");
#if NET_FW
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledToModuleVirtual(iFoo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `Manual Func<IFoo, int>      Expression + .CompileToMethod()` | {elapsedMs}");
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledToModuleDirect(foo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `Manual (Func<FooImpl, int>) Expression + .CompileToMethod()` | {elapsedMs}");
#endif
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledViaScriptVirtual(iFoo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Virtual | `CSharpScript.Eval. Func<IFoo, int> to lambda` | {elapsedMs}");
            sw.Restart();
            for (int i = 0; i < iterationCount; i++)
               compiledViaScriptDirect(foo);
            elapsedMs = sw.ElapsedMilliseconds;
            Console.WriteLine($"Direct  | `CSharpScript.Eval. Func<FooImpl, int> to lambda` | {elapsedMs}");
            //sw.Restart();
            //for (int i = 0; i < iterationCount; i++)
            //{
            //   int result = (int)iBarMethodInfo.Invoke(iFoo, null);
            //}
            //elapsedMs = sw.ElapsedMilliseconds;
            //Console.WriteLine($"Virtual | `MethodInfo.Invoke(FooImpl, Bar)` | {elapsedMs}");
            //sw.Restart();
            //for (int i = 0; i < iterationCount; i++)
            //{
            //   int result = (int)barMethodInfo.Invoke(foo, null);
            //}
            //elapsedMs = sw.ElapsedMilliseconds;
            //Console.WriteLine($"Direct  | `MethodInfo.Invoke(IFoo, Bar)` | {elapsedMs}");
         }
         round++;
         goto start;
      }
      static LambdaExpression GenerateBarExprClosure(IFoo foo, bool asInterfaceCall)
      {
         var fooType = asInterfaceCall ? typeof(IFoo) : foo.GetType();
         var methodInfo = fooType.GetMethod(nameof(IFoo.Bar));
         var instance = Expression.Constant(foo, fooType);
         var call = Expression.Call(instance, methodInfo);
         var lambda = Expression.Lambda(call);
         return lambda;
      }
      static LambdaExpression GenerateBarExprArg<TInput>()
      {
         var fooType = typeof(TInput);
         var methodInfo = fooType.GetMethod(nameof(IFoo.Bar));
         var instance = Expression.Parameter(fooType, "foo");
         var call = Expression.Call(instance, methodInfo);
         var lambda = Expression.Lambda(call, instance);
         return lambda;
      }
      static Func<int> CompileBar(IFoo foo, bool asInterfaceCall)
      {
         var lambda = GenerateBarExprClosure(foo, asInterfaceCall);
         var compiledFunction = (Func<int>)lambda.Compile();
         return compiledFunction;
      }
      static Func<TInput, int> CompileBar<TInput>()
      {
         var lambda = GenerateBarExprArg<TInput>();
         var compiledFunction = (Func<TInput, int>)lambda.Compile();
         return compiledFunction;
      }
      static Func<int> CompileFastBar(IFoo foo, bool asInterfaceCall)
      {
         var lambda = GenerateBarExprClosure(foo, asInterfaceCall);
         var compiledFunction = (Func<int>)lambda.CompileFast(true);
         return compiledFunction;
      }
      static Func<TInput, int> CompileFastBar<TInput>()
      {
         var lambda = GenerateBarExprArg<TInput>();
         var compiledFunction = (Func<TInput, int>)lambda.CompileFast(true);
         return compiledFunction;
      }
#if NET_FW
      static Func<TInput, int> CompileToModule<TInput>()
      {
         var fooType = typeof(TInput);
         var methodInfo = fooType.GetMethod(nameof(IFoo.Bar));
         var instance = Expression.Parameter(fooType, "foo");
         var call = Expression.Call(instance, methodInfo);
         var lambda = Expression.Lambda(call, instance);
         var asmName = new AssemblyName(fooType.Name);
         var asmBuilder = AssemblyBuilder.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
         var moduleBuilder = asmBuilder.DefineDynamicModule(fooType.Name);
         var typeBuilder = moduleBuilder.DefineType(fooType.Name, TypeAttributes.Public);
         var methodBuilder = typeBuilder.DefineMethod(nameof(IFoo.Bar), MethodAttributes.Static, typeof(int), new[] { fooType });
         Expression.Lambda<Action>(lambda).CompileToMethod(methodBuilder);
         var createdType = typeBuilder.CreateType();
         var mi = createdType.GetMethods(BindingFlags.NonPublic | BindingFlags.Static)[1];
         var func = Delegate.CreateDelegate(typeof(Func<TInput, int>), mi);
         return (Func<TInput, int>)func;
      }
#endif
      static Func<TInput, int> CompileViaScript<TInput>()
      {
         ScriptOptions scriptOptions = ScriptOptions.Default;
         //Add reference to mscorlib
         var mscorlib = typeof(System.Object).Assembly;
         var systemCore = typeof(System.Func<>).Assembly;
         var thisAssembly = typeof(IFoo).Assembly;
         scriptOptions = scriptOptions.AddReferences(mscorlib, systemCore, thisAssembly);
         var result = CSharpScript.EvaluateAsync<Func<TInput, int>>("it => it.Bar()", options: scriptOptions).Result;
         return result;
      }
      static Expression<Func<TInput, int>> GenerateExprFromScript<TInput>()
      {
         ScriptOptions scriptOptions = ScriptOptions.Default;
         //Add reference to mscorlib
         var mscorlib = typeof(System.Object).Assembly;
         var systemCore = typeof(System.Func<>).Assembly;
         var thisAssembly = typeof(IFoo).Assembly;
         scriptOptions = scriptOptions.AddReferences(mscorlib, systemCore, thisAssembly);
         var result = CSharpScript.EvaluateAsync<Expression<Func<TInput, int>>>("it => it.Bar()", options: scriptOptions).Result;
         return result;
      }
      static Func<TInput, int> CompileBarFromExprFromScript<TInput>()
      {
         var lambda = GenerateExprFromScript<TInput>();
         var compiledFunction = (Func<TInput, int>)lambda.Compile();
         return compiledFunction;
      }
      static Func<TInput, int> CompileFastBarFromExprFromScript<TInput>()
      {
         var lambda = GenerateExprFromScript<TInput>();
         var compiledFunction = (Func<TInput, int>)lambda.CompileFast(true);
         return compiledFunction;
      }
   }
}
How to use CSharpScript: 
https://joshvarty.com/2015/10/15/learn-roslyn-now-part-14-intro-to-the-scripting-api/ 
https://www.strathweb.com/2018/01/easy-way-to-create-a-c-lambda-expression-from-a-string-with-roslyn/