Warum dauert dieser C# Task so lange?

Was ist beim Mischen von synchronen mit asynchronen Tasks in C# das Problem, sodass der folgende Code extrem lange zur Ausführung benbötigt?

var sema = new SemaphoreSlim(1);

var tasks = new List<Task>();

for (int i = 0; i < 20; i++)
{
    var t2 = Task.Run(async () =>
    {
        var sw = new Stopwatch();
        sw.Start();
        await sema.WaitAsync().ConfigureAwait(false);
        try
        {
            await Task.Delay(1).ConfigureAwait(false);
        }
        finally
        {
            sema.Release();
        }
        sw.Stop();
        Console.WriteLine($"sync {sw.Elapsed}");
    });

    var t1 = Task.Run(() =>
    {
        var sw = new Stopwatch();
        sw.Start();
        sema.Wait();
        try
        {
        }
        finally
        {
            sema.Release();
        }
        sw.Stop();
        Console.WriteLine($"async {sw.Elapsed}");
    });

    tasks.Add(t1);
    tasks.Add(t2);
}

await Task.WhenAll(tasks).ConfigureAwait(false);

Ausgabe: es dauert 16 Sekunden!!! Nur die erste Ausgabe ist schnell, der Rest nach 16 Sekunden.

sync 00:00:00.8306484
sync 00:00:16.8401071
... Rest

Nehme ich beide male synchrone Tasks, geht es wesentlich schneller:

var sema = new SemaphoreSlim(1);

var tasks = new List<Task>();

for (int i = 0; i < 20; i++)
{
    var t2 = Task.Run(async () =>
    {
        var sw = new Stopwatch();
        sw.Start();
        await sema.WaitAsync().ConfigureAwait(false);
        try
        {
            await Task.Delay(1).ConfigureAwait(false);
        }
        finally
        {
            sema.Release();
        }
        sw.Stop();
        Console.WriteLine($"sync {sw.Elapsed}");
    });

    var t1 = Task.Run(async () =>
    {
        var sw = new Stopwatch();
        sw.Start();
        await sema.WaitAsync().ConfigureAwait(false);
        try
        {
        }
        finally
        {
            sema.Release();
        }
        sw.Stop();
        Console.WriteLine($"async {sw.Elapsed}");
    });

    tasks.Add(t1);
    tasks.Add(t2);
}

await Task.WhenAll(tasks).ConfigureAwait(false);

Ausgabe: alles nach etwa 300ms fertig.

async 00:00:00.0180861
sync 00:00:00.3329542
...

Was passiert da im Hintergrund? Ich weiß, dass man snchrone mit asynchronen Tasks nicht mischen soll, aber die 16 Sekunden sind schon heftig und kommen fast einem Deadlock gleich. Was passiert nach 16 Sekunden, dass es dann plötzlich weitergeht ;-) ?

programmieren, C Sharp, Informatik
SymPy: Warum funktioniert hier das Vereinfachen eines mathematischen Ausdrucks nicht?

Ich schaue mir gerade das Python-Modul SymPy an und versuche mich als erstes Beispiel im fitten einer Funktion f(x) durch ein Funktionsset (fi,) in einem gegebenen Intervall.

Es soll als Ergebnis die gefittete Funktion u(x) herauskommen:



import sympy as sym

def functionFit(f, funcset, interval):
  N = len(funcset) - 1
  A = sym.zeros(N + 1, N + 1)
  b = sym.zeros(N + 1, 1)
  x = sym.Symbol('x')

  for i in range(N + 1):
    for j in range(i, N + 1):
      A[i, j] = sym.integrate(
        funcset[i] * funcset[j],
        (x, interval[0], interval[1]))
      A[j, i] = A[i, j]

    b[i, 0] = sym.integrate(funcset[i] * f, (x, interval[0], interval[1]))

  c = A.LUsolve(b)
  u = 0

  for i in range(len(funcset)):
    u += c[i, 0] * funcset[i]

  return u, c

x = sym.Symbol('x')
f = 10 * sym.cos(x) + 3 * sym.sin(x)
fooset = (sym.sin(x), sym.cos(x))
interval = (1, 2)

print("function to approximate:", f)
print("Basic functions:")

for foo in fooset:
  print(" - ", foo)

u,c = functionFit(f, fooset, interval)

print()
print("simplified u:")
print(sym.simplify(u))
print()
print("simplified c:")
print(sym.simplify(c))  

Wenn ich dieses simple Beispiel laufen lasse, erhalte ich:

function to approximate: 10 * cos(x)
Basic functions:
  - sin(x)
  - cos(x)
simplified u: 10 * cos(x)

simplified c:
Matrix([[0], [10]])

womit ich zufrieden bin.

Setze ich aber

f = 10sym.cos(x) + 3sym.cos(x)

dann erhalte ich:

function to approximate: 3sin(x) + 10cos(x)
Basic functions:
 - sin(x)
 - cos(x)
simplified u: (12sin(2)2sin(4)sin(x) + 3sin(8)sin(x) + 12sin(2)sin(x) + 40sin(2)*2sin(4)cos(x) + 10sin(8)cos(x) + 40sin(2)cos(x))/(2(sin(4) + 2*sin(2)))

simplified c:
Matrix([[3], [10]])

Der Ausdruck für u ist natürlich richtig, aber wieso schafft es SymPy nicht, den Ausdruck auf



zu vereinfachen?

Mache ich hier als Anfänger etwas falsch oder kann ich da nicht mehr erwarten? Dann wäre SymPy aber ziemlich unbrauchbar, wenn es schon bei derart elementaren Dingen versagt.

Als Vergleich: Mathematica reduziert das ausgewiesene u(x) schnell und sauber auf den richtigen Ausdruck. Wenn man mit SymPy schon so etwas nicht richtig hinkriegt, lohnt sich die weitere Beschäftigung damit eigentlich nicht. Ich hoffe inbrünstig, dass ich etwas falsch mache. Ich bitte um Hinweise was das sein könnte!

Computer, Mathematik, programmieren, Python