Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.07.13 14:51
Оценка: :)
Декомпильнул тут (Решарпером) один из наших небольших классов и по началу его не узнал. Вроде бы в исходниках был малюсенький такой классик. На страничку:
using Nemerle;
using Nemerle.Collections;
using Nemerle.Extensions;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;

namespace N2.Internal
{
  [Record]
  [StructuralEquality]
  public class RecoveryResult
  {
    public StartPos    : int;
    public RuleEndPos  : int;
    public EndPos      : int;
    public StartState  : int;
    public StackLength : int;
    public Stack       : list[RecoveryStackFrame].Cons;
    public Text        : string;
    public FailPos     : int;

    public BeforeFail     : string { get { Text.Substring(0, FailPos) } }
    public Skiped         : string { get { Text.Substring(FailPos, StartPos - FailPos) } }
    public SkipedCount    : int    { get { StartPos - FailPos } }
    public Recovered      : string { get { try Text.Substring(StartPos, RecoveredCount)            catch "<unknown>" } }
    public RecoveredHead  : string { get { try Text.Substring(StartPos, RecoveredHeadCount)        catch "<unknown>" } }
    public RecoveredTail  : string { get { try Text.Substring(GetRuleEndPos(), RecoveredTailCount) catch "<unknown>" } }

    public RecoveredCount     : int    { get { EndPos - StartPos } }
    public RecoveredHeadCount : int    { get { GetRuleEndPos() - StartPos } }
    public RecoveredTailCount : int    { get { EndPos - GetRuleEndPos() } }

    GetRuleEndPos() : int { if (RuleEndPos < 0) StartPos else RuleEndPos }

    public override ToString() : string
    {
      $<#$(Stack.Head) StartState=$StartState  Skiped="$Skiped"  Recovered: Head="$RecoveredHead" Tail=="$RecoveredTail" #>
    }
  }
}


А в результате получилось (и ведь не выбросишь не капли):
// Type: N2.Internal.RecoveryResult
// Assembly: N2.Runtime, Version=896.0.0.0, Culture=neutral, PublicKeyToken=e080a9c724e2bfcd
// MVID: 6EF974BD-7AC2-4A0B-94B4-C3222EE7A587
// Assembly location: G:\P\Nitra\N2\N2.Runtime\bin\Debug\N2.Runtime.dll

using Nemerle.Core;
using Nemerle.Internal;
using System;
using System.Collections;
using System.Collections.Generic;

namespace N2.Internal
{
  public class RecoveryResult : IEquatable<RecoveryResult>, IStructuralEquatable
  {
    public readonly int StartPos;
    public readonly int RuleEndPos;
    public readonly int EndPos;
    public readonly int StartState;
    public readonly int StackLength;
    public readonly list<RecoveryStackFrame>.Cons Stack;
    public readonly string Text;
    public readonly int FailPos;

    public string BeforeFail { get { return this.Text.Substring(0, this.FailPos); } }
    public string Skiped { get { return this.Text.Substring(this.FailPos, checked (this.StartPos - this.FailPos)); } }
    public int SkipedCount { get { return checked (this.StartPos - this.FailPos); } }
    public string Recovered
    {
      get
      {
        string str;
        try
        {
          str = this.Text.Substring(this.StartPos, this.RecoveredCount);
        }
        catch (Exception ex)
        {
          str = "<unknown>";
        }
        return str;
      }
    }

    public string RecoveredHead
    {
      get
      {
        string str;
        try
        {
          str = this.Text.Substring(this.StartPos, this.RecoveredHeadCount);
        }
        catch (Exception ex)
        {
          str = "<unknown>";
        }
        return str;
      }
    }

    public string RecoveredTail
    {
      get
      {
        string str;
        try
        {
          str = this.Text.Substring(this.GetRuleEndPos(), this.RecoveredTailCount);
        }
        catch (Exception ex)
        {
          str = "<unknown>";
        }
        return str;
      }
    }

    public int RecoveredCount { get { return checked (this.EndPos - this.StartPos); } }
    public int RecoveredHeadCount { get { return this.GetRuleEndPos() - this.StartPos; } }
    public int RecoveredTailCount { get { return checked this.EndPos - this.GetRuleEndPos(); } }

    [RecordCtor]
    public RecoveryResult([MappedMember("StartPos")] int startPos, [MappedMember("RuleEndPos")] int ruleEndPos, [MappedMember("EndPos")] int endPos, [MappedMember("StartState")] int startState, [MappedMember("StackLength")] int stackLength, [MappedMember("Stack")] list<RecoveryStackFrame>.Cons stack, [MappedMember("Text")] string text, [MappedMember("FailPos")] int failPos)
    {
      this.StartPos = startPos;
      this.RuleEndPos = ruleEndPos;
      this.EndPos = endPos;
      this.StartState = startState;
      this.StackLength = stackLength;
      this.Stack = stack;
      this.Text = text;
      this.FailPos = failPos;
    }

    public static bool operator !=(RecoveryResult first, RecoveryResult second)
    {
      return !(first == second);
    }

    public static bool operator ==(RecoveryResult first, RecoveryResult second)
    {
      if ((object) first != null)
        return first.Equals(second);
      return (object) second == null;
    }

    public int GetHashCode(IEqualityComparer _comparer)
    {
      return this.GetHashCode();
    }

    public bool Equals(object other, IEqualityComparer _comparer)
    {
      return this.Equals(other);
    }

    public override int GetHashCode()
    {
      int num1 = 0 + this.StartPos;
      int num2 = num1 + (num1 << 10);
      int num3 = (num2 ^ num2 >> 6) + this.RuleEndPos;
      int num4 = num3 + (num3 << 10);
      int num5 = (num4 ^ num4 >> 6) + this.EndPos;
      int num6 = num5 + (num5 << 10);
      int num7 = (num6 ^ num6 >> 6) + this.StartState;
      int num8 = num7 + (num7 << 10);
      int num9 = (num8 ^ num8 >> 6) + this.StackLength;
      int num10 = num9 + (num9 << 10);
      int num11 = num10 ^ num10 >> 6;
      list<RecoveryStackFrame>.Cons cons = this.Stack;
      int num12 = 0;
      if ((list<RecoveryStackFrame>) cons != (list<RecoveryStackFrame>) null)
        num12 = cons.GetHashCode();
      int num13 = num12;
      int num14 = num11 + num13;
      int num15 = num14 + (num14 << 10);
      int num16 = num15 ^ num15 >> 6;
      string str = this.Text;
      int num17 = 0;
      if (str != (string) null)
        num17 = str.GetHashCode();
      int num18 = num17;
      int num19 = num16 + num18;
      int num20 = num19 + (num19 << 10);
      int num21 = (num20 ^ num20 >> 6) + this.FailPos;
      int num22 = num21 + (num21 << 10);
      return num22 ^ num22 >> 6;
    }

    public override bool Equals(object other)
    {
      object obj = other;
      if (obj is RecoveryResult)
        return this.EqualsImpl((RecoveryResult) obj);
      else
        return false;
    }

    public bool Equals(RecoveryResult other)
    {
      return this.EqualsImpl(other);
    }

    private int GetRuleEndPos()
    {
      if (this.RuleEndPos < 0)
        return this.StartPos;
      else
        return this.RuleEndPos;
    }

    public override string ToString()
    {
      string[] strArray = new string[10];
      int index1 = 0;
      string str1 = Convert.ToString((object) this.Stack.Head);
      strArray[index1] = str1;
      int index2 = 1;
      string str2 = " StartState=";
      strArray[index2] = str2;
      int index3 = 2;
      string str3 = Convert.ToString(this.StartState);
      strArray[index3] = str3;
      int index4 = 3;
      string str4 = "  Skiped=\"";
      strArray[index4] = str4;
      int index5 = 4;
      string str5 = Convert.ToString(this.Skiped);
      strArray[index5] = str5;
      int index6 = 5;
      string str6 = "\"  Recovered: Head=\"";
      strArray[index6] = str6;
      int index7 = 6;
      string str7 = Convert.ToString(this.RecoveredHead);
      strArray[index7] = str7;
      int index8 = 7;
      string str8 = "\" Tail==\"";
      strArray[index8] = str8;
      int index9 = 8;
      string str9 = Convert.ToString(this.RecoveredTail);
      strArray[index9] = str9;
      int index10 = 9;
      string str10 = "\" ";
      strArray[index10] = str10;
      return string.Concat(strArray);
    }

    protected virtual bool EqualsImpl(RecoveryResult other)
    {
      if ((object) other == null)
        return false;
      else
        return this.FailPos == other.FailPos && (string.Equals(this.Text, other.Text) && (EqualityComparer<list<RecoveryStackFrame>.Cons>.Default.Equals(this.Stack, other.Stack) && (this.StackLength == other.StackLength && (this.StartState == other.StartState && (this.EndPos == other.EndPos && (this.RuleEndPos == other.RuleEndPos && this.StartPos == other.StartPos))))));
    }
  }
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: _NN_ www.nemerleweb.com
Дата: 30.07.13 16:07
Оценка:
Здравствуйте, VladD2, Вы писали:

Хороший кстати вопрос, насчет декомпиляции в макросы.
В принципе компилятор может знать какие трансформации проходят и имея неизменяемый AST это все дело могло бы быть обратимо...
И тогда Resharper бы выдал оригинальный код.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: nikov США http://www.linkedin.com/in/nikov
Дата: 30.07.13 16:44
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Декомпильнул тут (Решарпером) один из наших небольших классов и по началу его не узнал. Вроде бы в исходниках был малюсенький такой классик.


VD>
VD>    public override int GetHashCode()
VD>    {
VD>      int num1 = 0 + this.StartPos;
VD>      int num2 = num1 + (num1 << 10);
VD>      int num3 = (num2 ^ num2 >> 6) + this.RuleEndPos;
VD>      int num4 = num3 + (num3 << 10);
VD>      int num5 = (num4 ^ num4 >> 6) + this.EndPos;
VD>      int num6 = num5 + (num5 << 10);
VD>      int num7 = (num6 ^ num6 >> 6) + this.StartState;
VD>


Hash code беспонтово считается. Где bit shuffling без потерь информации: умножения на большие нечётные константы, XOR-ы с масками, циклические сдвиги подстроки битов, сложения с большими константами?
Re: J vs. Other languages. До сих пор привыкнуть не могу :)
От: Аноним  
Дата: 30.07.13 17:19
Оценка: -2 :)
Здесь все коротко, просто и ясно с одного взгляда:
{:&([+/\@|.@]^:[1x 0"0)


А тут увидел недавно пример на C# и не сразу понял, что он вычисляет и каким способом. Только чтобы глазами по нему пробежаться, уже сколько времени требуется! А если мне на другой метод посмотреть понадобится, так это мне, что, скроллировать текст придётся???
class Program
{
    public static int Fib(int n)
    {
        int a = 0;
        int b = 1;
        for (int i = 0; i < n; i++)
        {
            int temp = a;
            a = b;
            b = temp + b;
        }
        return a;
    }
}
Re: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: IT Россия linq2db.com
Дата: 31.07.13 00:07
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Декомпильнул тут (Решарпером) один из наших небольших классов и по началу его не узнал. Вроде бы в исходниках был малюсенький такой классик. На страничку:


Ну дык, у Немерле ещё тот оптимизатор кода. Помнится, когда он научился компилировать BLToolkit, то размер сборки был толи в 2, толи в 3 раза больше, чем аналогичный результат выдаваемый шарпом.
... << RSDN@Home 1.2.0 alpha 5 rev. 69>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.07.13 13:35
Оценка:
Здравствуйте, nikov, Вы писали:

N>Hash code беспонтово считается. Где bit shuffling без потерь информации: умножения на большие нечётные константы, XOR-ы с масками, циклические сдвиги подстроки битов, сложения с большими константами?


Я вообще не знаю кто эту химию нагородил.

Если хочешь, можешь помочь проекту и тряхнуть стариной, сделать идеальную, с твоей точки зрения, реализацию.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: catbert  
Дата: 31.07.13 14:21
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, nikov, Вы писали:


N>>Hash code беспонтово считается. Где bit shuffling без потерь информации: умножения на большие нечётные константы, XOR-ы с масками, циклические сдвиги подстроки битов, сложения с большими константами?


VD>Я вообще не знаю кто эту химию нагородил.


Я нагородил. Почему без умножений? Вот почему: http://www.rsdn.ru/forum/nemerle/4429772.1
Автор: VladD2
Дата: 21.09.11
Re[3]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: nikov США http://www.linkedin.com/in/nikov
Дата: 31.07.13 17:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Если хочешь, можешь помочь проекту и тряхнуть стариной, сделать идеальную, с твоей точки зрения, реализацию.


Я ж говорил: пока я в MS, мне без одобрения наших юристов этим никак нельзя заниматься.
Re[4]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Аноним  
Дата: 31.07.13 18:17
Оценка:
Здравствуйте, catbert, Вы писали:

C>Здравствуйте, VladD2, Вы писали:


VD>>Здравствуйте, nikov, Вы писали:


N>>>Hash code беспонтово считается. Где bit shuffling без потерь информации: умножения на большие нечётные константы, XOR-ы с масками, циклические сдвиги подстроки битов, сложения с большими константами?


VD>>Я вообще не знаю кто эту химию нагородил.


C>Я нагородил. Почему без умножений? Вот почему: http://www.rsdn.ru/forum/nemerle/4429772.1
Автор: VladD2
Дата: 21.09.11



Сейчас умножение в 20-300 раз медленнее доступа в память в случае промоха кеша....
Re[5]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Аноним  
Дата: 31.07.13 18:33
Оценка:
Здравствуйте, Аноним, Вы писали:

Сейчас умножение в 20-300 раз быстрее доступа в память в случае промоха кеша....
Re[4]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.07.13 18:47
Оценка:
Здравствуйте, nikov, Вы писали:

N>Я ж говорил: пока я в MS, мне без одобрения наших юристов этим никак нельзя заниматься.


Что-то я не пойму, как реализация алгоритма хэшкода связана с твоей работой в МС. Ну, да ничего не поделать.

Лично мне в общем-то по фигу как там хэш получается. Я и обычными ^ обошелся бы. А где нужна скорость и качество можно и руками своять.

ЗЫ

Возвращайся в ДжетБрэйнс. Вместе Н2 будем ваять.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.07.13 19:09
Оценка:
Здравствуйте, IT, Вы писали:

IT>Ну дык, у Немерле ещё тот оптимизатор кода. Помнится, когда он научился компилировать BLToolkit, то размер сборки был толи в 2, толи в 3 раза больше, чем аналогичный результат выдаваемый шарпом.


Если честно, не помню такого (возможно дело в классах под лямбды было). Но тут явно не в этом дело. Просто привыкаешь, что кучу рутинного кода можно заменить двумя макросами, а синтаксис позволяет писать многие вещи в строку, а не разносить на пять (try-и, например).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Аноним  
Дата: 31.07.13 19:38
Оценка:
Здравствуйте, catbert, Вы писали:

http://ru.wikipedia.org/wiki/FNV


function FNV1aHash(const buf; len: Integer): LongWord;
var
  pb: PByte;
  i: Integer;
begin
  pb := PByte(@buf);
  Result := $811C9DC5;
  for i := len downto 1 do
  begin
    Result := (Result xor pb^) * $01000193;
    Inc(pb);
  end;
end;
Re[3]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: IT Россия linq2db.com
Дата: 31.07.13 23:38
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Ну дык, у Немерле ещё тот оптимизатор кода. Помнится, когда он научился компилировать BLToolkit, то размер сборки был толи в 2, толи в 3 раза больше, чем аналогичный результат выдаваемый шарпом.


VD>Если честно, не помню такого (возможно дело в классах под лямбды было).


У вас же есть тестовые проекты под C#. Возьмите и сравните. Я в своё время тоже этого дела надекомпилировался и проблема там не в лямбдах, а в ПМ, и, в результате, в любом банальном if. Код там может по производительности и более менее эффективный генерируется, но лишнего мусора тоже хватает, явно больше чем надо.

VD>Но тут явно не в этом дело. Просто привыкаешь, что кучу рутинного кода можно заменить двумя макросами, а синтаксис позволяет писать многие вещи в строку, а не разносить на пять (try-и, например).


Ну это понятно. А когда у вас до оптимизаторов руки дойдут?
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Аноним  
Дата: 01.08.13 08:18
Оценка:
Здравствуйте, IT, Вы писали:

IT>Ну это понятно. А когда у вас до оптимизаторов руки дойдут?


Лапши захотелось?
Re[4]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.08.13 15:08
Оценка:
Здравствуйте, IT, Вы писали:

IT>У вас же есть тестовые проекты под C#. Возьмите и сравните. Я в своё время тоже этого дела надекомпилировался и проблема там не в лямбдах, а в ПМ, и, в результате, в любом банальном if. Код там может по производительности и более менее эффективный генерируется, но лишнего мусора тоже хватает, явно больше чем надо.


Тут скорее проблема в декомпиляторе Reflector вообще кривой. ILSpy нормально декомпилирует, но иногда врет. Нет там ничего лишнего.

VD>>Но тут явно не в этом дело. Просто привыкаешь, что кучу рутинного кода можно заменить двумя макросами, а синтаксис позволяет писать многие вещи в строку, а не разносить на пять (try-и, например).


IT>Ну это понятно. А когда у вас до оптимизаторов руки дойдут?


А на фиг одни нужны? Скорость такая же. Если какие-то шероховатости и есть, то оптимизатор jit-а и gnen-а их устраняет. Да и про какие-то страшные не оптимальные конструкции это ты преувеличиваешь. Я этот декомпилированный код почти каждый день смотрю. Там все ОК.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: IT Россия linq2db.com
Дата: 01.08.13 23:39
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>У вас же есть тестовые проекты под C#. Возьмите и сравните. Я в своё время тоже этого дела надекомпилировался и проблема там не в лямбдах, а в ПМ, и, в результате, в любом банальном if. Код там может по производительности и более менее эффективный генерируется, но лишнего мусора тоже хватает, явно больше чем надо.

VD>Тут скорее проблема в декомпиляторе Reflector вообще кривой. ILSpy нормально декомпилирует, но иногда врет. Нет там ничего лишнего.

А куда оно делось? То, что было это 100%, это я хорошо помню ещё когда с дебагером возился. Неужели кто-то этим специально занимался?

IT>>Ну это понятно. А когда у вас до оптимизаторов руки дойдут?

VD>А на фиг одни нужны? Скорость такая же. Если какие-то шероховатости и есть, то оптимизатор jit-а и gnen-а их устраняет. Да и про какие-то страшные не оптимальные конструкции это ты преувеличиваешь. Я этот декомпилированный код почти каждый день смотрю. Там все ОК.

Понятно. Другого ответа трудно было ожидать.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.08.13 21:37
Оценка:
Здравствуйте, IT, Вы писали:

IT>А куда оно делось? То, что было это 100%, это я хорошо помню ещё когда с дебагером возился. Неужели кто-то этим специально занимался?


Я не знаю что ты помнишь. Давай смотреть на конкретные примеры.

IT>Понятно. Другого ответа трудно было ожидать.


Приятно что та свое невнятный вопрос ты получил ожидаемый ответ. Еще раз повторяюсь. Приводи примеры проблем — будем смотреть.

Я вижу только дублирующиеся переменные в дебаге, что проблемы не составляет, так как джит в релизе их выкидывает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 08.08.13 12:16
Оценка: -1 :)
Здравствуйте, VladD2, Вы писали:

VD>А на фиг одни нужны? Скорость такая же. Если какие-то шероховатости и есть, то оптимизатор jit-а и gnen-а их устраняет. Да и про какие-то страшные не оптимальные конструкции это ты преувеличиваешь. Я этот декомпилированный код почти каждый день смотрю. Там все ОК.


"Декомпильнул тут (Решарпером) один из наших небольших классов и по началу его не узнал"

"Я этот декомпилированный код почти каждый день смотрю. Там все ОК."

Re[6]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.08.13 13:27
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>"Декомпильнул тут (Решарпером) один из наших небольших классов и по началу его не узнал"


I>"Я этот декомпилированный код почти каждый день смотрю. Там все ОК."


I>


Да, действительно . Влезть в середину разговора, вырвать из контекста пару строк. Ничего не понять и начать -ы ставить. Это несомненно . Я бы на твое месте со стыда сгорел.

Не узнал я его потому что на шарпе приходится писать существенно больше кода, а не потому что код не оптимальный получается.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.