Матрично-алгебраическая декомпозиция дизайна - PullRequest
1 голос
/ 30 апреля 2009

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

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

Некоторое время назад я наткнулся на метод в книге о разработке SOA под названием «Разложение матрицы», в котором используется матрица выходных данных и их зависимости от входных данных, применяется некоторая форма матричной алгебры и может генерироваться диаграммы бизнес-процессов для этих зависимостей.

Я знаю, что есть веб-инструмент, доступный на http://www.designdecomposition.com/, однако он ограничен числом зависимостей ввода / вывода, которые вы можете иметь. Я попытался найти алгоритмический источник для этого инструмента (чтобы я мог попытаться реализовать его самостоятельно без ограничения размера), однако мне не повезло.

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

Приветствия

Айдос

РЕДАКТИРОВАТЬ:

Я объясню мотивацию:

Исходный код был написан для системы, которая вычисляла все значения (около 60) каждый раз, когда пользователь выполнял операцию (добавление, удаление или изменение определенных свойств элемента). Этот код был написан более десяти лет назад и определенно показывает признаки старения - другие добавили более сложные вычисления в систему, и теперь мы получаем совершенно необоснованную производительность (до 2 минут до того, как управление возвращается пользователю). Было решено отделить вычисления от действий пользователя и предоставить кнопку для «пересчета» значений.

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

Здесь я хочу использовать метод матричной декомпозиции. Подход MD позволяет мне указать все входы и выходы и дает мне «самый простой» рабочий процесс, который я могу использовать для генерации всех выходов.

Затем я могу использовать этот «рабочий процесс», чтобы узнать приоритет вычислений, которые мне нужно выполнить, чтобы получить тот же результат без генерации каких-либо исключений. Он также показывает мне, какие части системы вычислений я могу распараллелить и где будут точки ветвления и соединения (пока я не буду беспокоиться об этой части). На данный момент все, что у меня есть, - это безумно большая матрица с множеством зависимостей, в которой не видно, с чего начать.

Я уточню из моего комментария немного больше:

Я не хочу использовать решение из процесса EA в реальной программе. Я хочу взять матрицу зависимостей и разложить ее на модули, которые затем буду кодировать вручную - это чисто вспомогательное средство проектирования - меня просто интересует, какие будут входы / выходы для этих модулей. В основном представление сложных взаимозависимостей между этими вычислениями, а также некоторое представление о приоритете.

Скажем, у меня A требует B и C. D требует A и E. F требует B, A и E, я хочу эффективно разделить проблемное пространство из сложного набора зависимостей в «рабочий процесс», который я могу исследовать для получить лучшее понимание. Как только у меня появится это понимание, я смогу придумать лучший дизайн / реализацию, которая по-прежнему будет удобочитаемой для человека, поэтому для примера, который я знаю, мне нужно вычислить A, затем C, затем D, а затем F.

-

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

Ответы [ 3 ]

2 голосов
/ 30 апреля 2009

kquinn, если это кусок кода, я думаю, он имеет в виду (я раньше работал там), то это уже решение черного ящика, которое никто не может понять как есть. Он не хочет, чтобы все было сложнее, на самом деле меньше. То, чего он пытается достичь, это целая куча взаимосвязанных вычислений.

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

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

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

0 голосов
/ 30 апреля 2009

Какой язык вы используете? Ваша проблема должна быть довольно легко смоделирована с использованием задач Java Executors и Future <>, но, возможно, аналогичная структура также доступна на выбранной вами платформе?

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

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

РЕДАКТИРОВАТЬ: Поскольку вы используете Java, я дам краткое описание предложения предложения:

-> Использовать пул потоков, чтобы легко распараллелить все вычисления

-> Решить взаимозависимости с помощью карты объектов Future <> или FutureTask <>: s, то есть, если вы используете переменные A, B и C, где A = B + C, сделайте что-то вроде этого:

static final Map<String, FutureTask<Integer>> mapping = ...
static final ThreadPoolExecutor threadpool = ...
FutureTask<Integer> a = new FutureTask<Integer>(new Callable<Integer>() {
            public Integer call() {
               Integer b = mapping.get("B").get();
               Integer c = mapping.get("C").get();
               return b + c;
            }
        }
    );
FutureTask<Integer> b = new FutureTask<Integer>(...);
FutureTask<Integer> c = new FutureTask<Integer>(...);
map.put("A", a);
map.put("B", a);
map.put("C", a);
for ( FutureTask<Integer> task : map.values() )
      threadpool.execute(task);

Теперь, если я не полностью выключен (и я вполне могу быть, это было некоторое время, так как я работал в Java), вы должны быть в состоянии решить очевидную проблему взаимоблокировки, настроив размер пула потоков, или используйте растущий пул потоков. (Вы все равно должны убедиться, что нет взаимозависимых задач, например, если A = B + C и B = A + 1 ...)

0 голосов
/ 30 апреля 2009

Если это, как вы говорите, «основная бизнес-логика», то вы действительно не хотите возиться с причудливыми декомпозициями и эволюционными алгоритмами, которые создают решение «черного ящика», которое никто в мире не понимает или способен к модификации. Я был бы очень удивлен, если бы любой из этих методов фактически дал какой-либо полезный результат; человеческий мозг все еще непостижимо более способен, чем любая другая машина, распутывать сложные отношения.

То, что вы хотите сделать, это традиционный рефакторинг: очистить отдельные процедуры, оптимизировать их и объединить их, где это возможно. Ваша цель - прояснить код, чтобы вашему преемнику не пришлось проходить тот же процесс.

...