Сравнение эффективности PascalABC.NET и C#


#41

Вот к примеру:

begin
  var sum := 0;
  
  {$omp parallel for}
  for var i := 1 to 10 do
    sum += i;
  
  writeln(sum);
end.

Декомпилируем. Вот нужные файлы:

Открываем:

// Decompiled with JetBrains decompiler
// Type: 0.$for_class0
// Assembly: 0, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 47A9A70D-80AB-4C11-9C01-6DF53C825BCC
// Assembly location: D:\1Cергей\Мои программы\Test\0.exe

namespace 0
{
  public class $for_class0
  {
    public int sum;

    public void $Init$()
    {
    }

    public void Method(int i)
    {
      this.sum += i;
    }

    public $for_class0()
    {
      this.$Init$();
    }
  }
}
// Decompiled with JetBrains decompiler
// Type: 0.Program
// Assembly: 0, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 47A9A70D-80AB-4C11-9C01-6DF53C825BCC
// Assembly location: D:\1Cергей\Мои программы\Test\0.exe

using 0;
using System;
using System.Threading.Tasks;

namespace 0
{
  [$UsedNsAttr(5, "\x0006System\x001ASystem.Collections.Generic\x0012System.Collections\tSystem.IO\x001ESystem.Runtime.InteropServices")]
  public class Program
  {
    public static bool $InParallelSection;
    public static object[] $intarr1;
    public static bool $is_init;

    public static void Main()
    {
      Program.$_Init_();
      Program.$_InitVariables_();
      Program.$Main();
      PABCSystem_implementation______.PABCSystem_implementation______.$Finalization();
    }

    public static void $Main()
    {
      int num1 = 0;
      if (!Program.$InParallelSection)
      {
        $for_class0 forClass0 = new $for_class0();
        forClass0.sum = num1;
        if (!PABCSystem.PABCSystem.OMP_NESTED)
          Program.$InParallelSection = true;
        Parallel.For(1, 11, new Action<int>(forClass0.Method));
        if (!PABCSystem.PABCSystem.OMP_NESTED)
          Program.$InParallelSection = false;
        num1 = forClass0.sum;
      }
      else
      {
        int num2 = 10;
        int num3 = 1;
        if (num3 <= num2)
        {
          while (true)
          {
            num1 += num3;
            if (num3 < num2)
              ++num3;
            else
              break;
          }
        }
      }
      PABCSystem.PABCSystem.Writeln((object) num1);
    }

    public static void $_Init_()
    {
      if (Program.$is_init)
        return;
      Program.$is_init = true;
      PABCSystem.PABCSystem.IsConsoleApplication = true;
      PABCSystem.PABCSystem.__CONFIG__.Add("locale", (object) "ru");
      PABCSystem.PABCSystem.__CONFIG__.Add("full_locale", (object) "ru-RU");
      PABCSystem_implementation______.PABCSystem_implementation______.$Initialization();
      PABCExtensions_implementation______.PABCExtensions_implementation______.$Initialization();
      __RedirectIOMode_implementation______.__RedirectIOMode_implementation______.$Initialization();
    }

    public static void $_InitVariables_()
    {
      Program.$InParallelSection = false;
    }
  }
}

Если надо - там ещё и IL код сразу, посмотреть как оно на самом деле в .exe сохранено. И если выделить что то в IL коде или в C# аналоге - то же самое выделяется в другой части.


#42

А что даст декомпиляция? Даже если удастся установить источник проблемы(неправильно сформированная конструкция, отсутствие примитивной оптимизации или что-то ещё), кто будет её исправлять? Ведь для этого, по сути, придётся весь компилятор перекапывать.


#43

С чего вдруг?

Речь шла про то что невозможно узнать что генерирует $omp, а я вот возразил что декомпиляцией можно увидеть. Просто перечитайте последние сообщения.


#44

Да нет, я Вас правильно понял. Про OMP -да, Вы правы, но вот оно уже нигде не используется. Я заменил его на конструкции чистого .NET.


#45

Правда, надо отметить, что OpenMP очень зря забросили. Хорошая вещь. Далеко не в каждом языке есть такая возможность.


#46

У меня тут такая мысль родилась. Что если проблема вовсе не в циклах, а в лямбда-выражениях? В соседнем топике уже сравнивали эффективность кода C# и PascalABC.NET и получили примерно одинаковые результаты. Паскаль отставал на единицы процентов, что уверенно можно считать статистической погрешностью. Но ведь вышеприведённая программа на Паскале и правда работает медленнее, чем на C#, в два раза. Код при этом абсолютно идентичен и никаких уловок не применялось. Единственное, на что можно обратить внимание - на лямбды, так как именно они участвуют в распараллеливании всех, в том числе ресурсоёмких, операций.


#47

И я, походу, не прав.

Проблема не в лямбдах, а в циклах. Пойду ка оптимизировать указатели. :smile: