Разорвать многоадресный делегат - PullRequest
0 голосов
/ 27 сентября 2019

У меня есть байтовый массив с примерно 8 миллионами записей.

Для каждой записи мне нужно выполнить динамическое количество операторов if.

Если я напишу это, если операторы жестко закодированы, чем этозанимает всего около 130 мс.

Я попытался написать класс, который содержит список классов правил, который содержит список классов условий.Это работает, но это занимает более 5 секунд.

Затем я изменил его, чтобы каждое условие из правила объединялось в многоадресном делегате.Этот метод занимает около 820 мс.

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

Проблема в том, что условия должны быть все истинными, ноесли одно правило истинно, мне не нужно проверять другие.

Так что мой вопрос: есть ли способ остановить многоадресный делегат от выполнения каждой функции?

Или, может быть, кто-тоесть лучшая идея для большей производительности?

Вот пример кода моей текущей ситуации.

Dictionary<DMatch, byte> Matches = new Dictionary<Rule.DMatch, byte>();
foreach (Rule rule in Rules.Rules)
{
    Matches.Add(rule.Match, rule.BW);
}
bool Result = true;

for (int i = 0; i < array.length; i++)
{
    foreach (KeyValuePair<DMatch, byte> kvpair in Matches)
    {
        Result = true;

        kvpair.Key(ref Result, array[i]);

        if (Result)
        {
            array[i] = kvpair.Value;
            break;
        }
    }

    if (!Result) bitbuffer[i] = 0;
}


public class Rule
{
    internal delegate void DMatch(ref bool Result, byte b);
    internal DMatch Match;

    internal void GetMatch()
    {
        foreach (Condition cd in Conditions)
        {
            Match += cd.GetMatch()
        }
    }
}

public class Condition
{
    internal DMatch GetMatch()
    {
        switch(Type)
        {
            case ConditionType.A:
                return A;
            case ConditionType.B:
                return B;
            case ConditionType.C:
                return C;
        }

        throw new Exeption();
    }

    internal void A(ref bool Result, byte b)
    {
        if (!Result) return;
        else
        {
            Result = ... ;
        }
    }

    internal void B(ref bool Result, byte b)
    {
        if (!Result) return;
        else
        {
            Result = ... ;
        }
    }

    internal void C(ref bool Result, byte b)
    {
        if (!Result) return;
        else
        {
            Result = ... ;
        }
    }
}

1 Ответ

0 голосов
/ 27 сентября 2019

Схематический код, я не проверял это:

// kvpair.Key(ref Result, array[i]);

foreach(var subscriber in kvpair.Key.GetInvocationList())
{
   subscriber.DynamicInvoke(ref Result, array[i]);
   if (! Result) break;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...