Парсер скриптового языка


Я делаю парсер скриптового языка и он, все складывается хорошо, но она занимает около 30 мс, чтобы сделать 30 или так чет/нечет проверки.

Профайлер мне говорит, что это занимает большую часть времени в InvokeOperator.Работы функции, но это не сказать мне много, потому что работы вызывается метод run на блок кода , который, в свою очередь, снова вызывает работы вызов и делает его очень трудно на самом деле определить, что так долго.

Вот GitHub РЕПО

Вот самые важные куски кода:

Stack<Token> solvingStack = new Stack<Token>();
for ( int i = 0 ; i < value.Count ; ++i )
{
   if ( value[ i ] is Operator )
   {
      Operator op = (Operator)value[ i ];
      if ( op.Type == OperatorType.PrefixUnary || op.Type == OperatorType.SufixUnary )
      {
         op.Operate( ( solvingStack.Pop() as Value ), new NoValue() );
      } else
      {
         Value second = (Value)solvingStack.Pop();
         Value result = op.Operate( ( solvingStack.Pop() as Value ), second );
         solvingStack.Push( result );
      }
   } else
   {
      solvingStack.Push( value[ i ] );
   }
}
Compiler.ExitScope();
if ( solvingStack.Count == 0 ) return new NoValue();
else return (Value)solvingStack.Peek();

Это как код обрабатывается после выражения инфиксные превращается в РПН. Маркер может быть оператор или значение, и значение может быть литерал, идентификатор, блок кода.

Несколько особый случай представляет собой функцию, потому что он не разбирается в РПН напрямую, а только код внутри. То есть ссылаться на оператора, он принимает массив аргументов, что и функция и выполняет функцию (которая наследуется из блоков кода, так он еще и работает то же самое, что показано здесь).

Что каждый оператор делает на разные типы ценностей определяется самим оператором операторов.файл CS.



888
7
задан 28 марта 2011 в 07:03 Источник Поделиться
Комментарии
2 ответа

Я не уверен, если эти узкие места, но они, по крайней мере, улучшена производительность.


  1. Заменить Стек с стек так вы не только толкает/выталкивание значения. Таким образом нет необходимости делать дорогие муляжи.

  2. Вы можете заменить

    if ( value[ i ] is Operator )
    {
    Operator op = (Operator)value[ i ];

    с

    Operator op = value[ i ] as Operator;
    if ( op != null ) // it was an Operator

    есть только один typecheck (х, г) вместо двух (х-г и (г) х).


  3. Вы можете заменить

    for ( int i = 0 ; i < value.Count ; ++i )

    с

    foreach(Token item in value)

    чтобы исключить операции с индексом стоимости[ I ].


3
ответ дан 30 апреля 2011 в 07:04 Источник Поделиться

Я предлагаю вам попробовать использовать профайлер какой-то для того, чтобы точно определить, где узкое место. Как только вы сделаете это, он будет гораздо легче найти, как этого избежать.

1
ответ дан 29 марта 2011 в 12:03 Источник Поделиться