sergeev: Ведь одна и та же функция может вызываться как из start, так и из init. Вот это и надо фиксировать.
на пальцах могу, а конкретно -думать нуно ))
примерно так:
считаем кол-во ф-ций, пусть их будет 4, пишем в шапке кода #define X 4
предполагаем, что максимальное количество вызовов на одном тике будет #define Y 100
имеем матрицу размерностью 4 х 100, инициализируем матрицу = -1
и теперь при вызове ф-ции в точке входа в ф-цию добавляем вызов счетчика(формирователя графа) который должен добавлять при входе в нашу матрицу на свободную строку код(1,2,3 или 4) на нужную позицию Х -кто вызвал
думаю, что Ваша задача больше похожа на сетевые графики, подозреваю, что мат.аппарат для сетевых графиков давно разработан - нужно погуглить
IgorM, способ, который вы предлагаете для хранения графа называется "матрица смежности". Для разреженных графов он очень неэкономичен (да и за архитектуру "полносвязный граф" программистов нужно бить и т.д.)
Гораздо лучше использовать список рёбер (т.е. храним одномерный массив структур, состоящих из 2х элементов - id вызывающей функции и id вызываемой функции; структуру можно дополнить дополнительными полями - счётчиками вызовов и т.д.)
IgorM, способ, который вы предлагаете для хранения графа называется "матрица смежности".
спс, хоть чтонить вспоминать начал, как никак ужо 15 лет прошло как изучал всю эту муть, которая в реальной жизни так и не пригодилась ))) - но не забывайте, что "упаковывание данных"(экономия памяти) - приведет к потере быстродействия из-за увеличения сложности мат.аппарата, хотя возможно я и ошибаюсь
MetaDriver: Доказательство невозможности за идею проканает?
Логгирование входов- выходов из функций легко делается на С++, там есть деструкторы и такая штучка как stack unwinding. Хотя... для того же С++ есть библиотеки, которые для произвольной точки в коде по стеку позволяют построить порядок вызова функций. . А так... каждый return означает дополнительные вызовы :-).
да. это и имел ввиду. Исходя из линейности MQL кода - будет дерево в чистом виде. Так как вершины не будут указывать друг на друга.
IgorM: имеем матрицу размерностью 4 х 100, инициализируем матрицу = -1 и теперь при вызове ф-ции в точке входа в ф-цию добавляем вызов счетчика(формирователя графа) который должен добавлять при входе в нашу матрицу на свободную строку код(1,2,3 или 4) на нужную позицию Х -кто вызвал
да. теперь понял. Но сдаётся мне этот подход действительно трудозатратный не столько в коде, сколько в в ресурсах и в подготовке к анализу. Для разветвления надо будет делать трехмерную матрицу. В общем вариант принимается. Но пока что его оставим до 4 страницы на резюме :)
думаю, что Ваша задача больше похожа на сетевые графики, подозреваю, что мат.аппарат для сетевых графиков давно разработан - нужно погуглить
Задача ни ноухау, и не новшество. Просто обычное построение графа функций. Не более. Матаппарата нового никакого, просто нужен до минимума упрощенный вариант.
Гораздо лучше использовать список рёбер (т.е. храним одномерный массив структур, состоящих из 2х элементов - id вызывающей функции и id вызываемой функции; структуру можно дополнить дополнительными полями - счётчиками вызовов и т.д.)
Евгений, именно это уже и сделано.
Но стопор случился. Уже третий день ни спать, ни пить.... :)
Не могу придумать, как сделать возврат из ребра(точнее узла потомка) к узлу родителя, чтоб перейти на новое ребро (новый узел потомка). Но чтоб соблюсти правило - используем только одну функцию трейсинга в начало функции исходного кода.
Не могу придумать, как сделать возврат из ребра к узлу, чтоб перейти на новую ветку.
И все одной только функцией, которая уже произвела проход вперед? Эт ты хватил - сделать возврат, ничего при этом не делая)) Ну ничего, уже вторая страничка закончилась, скоро Владимир не выдержит)))
alsu: И все одной только функцией, которая уже произвела проход вперед? Эт ты хватил - сделать возврат, ничего при этом не делая)) Ну ничего, уже вторая страничка закончилась, скоро Владимир не выдержит)))
Бог с ними, с этими страницами. Задача ведь интересная.
Понимаете, тут как можно.... Откат на узел родителя можно делать уже в новом вызове потомка. То есть при переходе на потомка система сначала опустится по дереву на уровень ниже, а потом поднимется в нового вызванного потомка.
Но в этом варианте нельзя сделать ветки с глубиной более двух. Так как система всегда будет возвращаться назад перед походом вперед. То есть все функции будут рисоваться на одном уровне.
Поэтому думается, что придется использовать какие-то массивы переменных, для идентификации текущего положения. чтоб идти дальше, а не возвращаться. Вот именно в этом возврате и сложность...
В прицепе "концептуальная заготовка", точнее пример реализации. на MT 5
Чтоб до ума довести нужно функции in() и out() переписать, дабы заставить работать со списком вызовов. Сейчас они тупо распечатывают входы и выходы в стандартный поток.
Плохая новость: Мечту топикстартера об одной трассировочной функции я не сберёг. Прости Сергеев. :)
Хорошая новость: Всё работает.
Руководство пользователя.
1. В начале каждой функции вставляется макрос "_in"
Бог с ними, с этими страницами. Задача ведь интересная.
Понимаете, тут как можно.... Откат на узел родителя можно делать уже в новом вызове потомка. То есть при переходе на потомка система сначала опустится по дереву на уровень ниже, а потом поднимется в нового вызванного потомка.
Но в этом варианте нельзя сделать ветки с глубиной более двух. Так как система всегда будет возвращаться назад перед походом вперед. То есть все функции будут рисоваться на одном уровне.
Поэтому думается, что придется использовать какие-то массивы переменных, для идентификации текущего положения. чтоб идти дальше, а не возвращаться. Вот именно в этом возврате и сложность...
А откуда все таки такая странная задача? Стоит ли расходовать усилия на сомнительные изыскания, если можно элементарно сделать ДВЕ функции -на вход и выход - и не париться?
Ведь одна и та же функция может вызываться как из start, так и из init. Вот это и надо фиксировать.
на пальцах могу, а конкретно -думать нуно ))
примерно так:
считаем кол-во ф-ций, пусть их будет 4, пишем в шапке кода #define X 4
предполагаем, что максимальное количество вызовов на одном тике будет #define Y 100
имеем матрицу размерностью 4 х 100, инициализируем матрицу = -1
и теперь при вызове ф-ции в точке входа в ф-цию добавляем вызов счетчика(формирователя графа) который должен добавлять при входе в нашу матрицу на свободную строку код(1,2,3 или 4) на нужную позицию Х -кто вызвал
думаю, что Ваша задача больше похожа на сетевые графики, подозреваю, что мат.аппарат для сетевых графиков давно разработан - нужно погуглить
ЗЫ: ну вотЪ ужо 2-я стр. топика ;)
IgorM, способ, который вы предлагаете для хранения графа называется "матрица смежности". Для разреженных графов он очень неэкономичен (да и за архитектуру "полносвязный граф" программистов нужно бить и т.д.)
Гораздо лучше использовать список рёбер (т.е. храним одномерный массив структур, состоящих из 2х элементов - id вызывающей функции и id вызываемой функции; структуру можно дополнить дополнительными полями - счётчиками вызовов и т.д.)
p.s. Матаппарат действительно давно разработан :)
IgorM, способ, который вы предлагаете для хранения графа называется "матрица смежности".
Доказательство невозможности за идею проканает?
там есть деструкторы и такая штучка как stack unwinding.
Хотя... для того же С++ есть библиотеки, которые для произвольной
точки в коде по стеку позволяют построить порядок вызова функций.
.
А так... каждый return означает дополнительные вызовы :-).
Дерево - частный случай графа.
да. это и имел ввиду. Исходя из линейности MQL кода - будет дерево в чистом виде. Так как вершины не будут указывать друг на друга.
IgorM:
имеем матрицу размерностью 4 х 100, инициализируем матрицу = -1
и теперь при вызове ф-ции в точке входа в ф-цию добавляем вызов счетчика(формирователя графа) который должен добавлять при входе в нашу матрицу на свободную строку код(1,2,3 или 4) на нужную позицию Х -кто вызвал
да. теперь понял. Но сдаётся мне этот подход действительно трудозатратный не столько в коде, сколько в в ресурсах и в подготовке к анализу. Для разветвления надо будет делать трехмерную матрицу.
В общем вариант принимается. Но пока что его оставим до 4 страницы на резюме :)
думаю, что Ваша задача больше похожа на сетевые графики, подозреваю, что мат.аппарат для сетевых графиков давно разработан - нужно погуглить
Задача ни ноухау, и не новшество. Просто обычное построение графа функций. Не более.
Матаппарата нового никакого, просто нужен до минимума упрощенный вариант.
Гораздо лучше использовать список рёбер (т.е. храним одномерный массив структур, состоящих из 2х элементов - id вызывающей функции и id вызываемой функции; структуру можно дополнить дополнительными полями - счётчиками вызовов и т.д.)
Евгений, именно это уже и сделано.
Но стопор случился. Уже третий день ни спать, ни пить.... :)
Не могу придумать, как сделать возврат из ребра(точнее узла потомка) к узлу родителя, чтоб перейти на новое ребро (новый узел потомка). Но чтоб соблюсти правило - используем только одну функцию трейсинга в начало функции исходного кода.
Не могу придумать, как сделать возврат из ребра к узлу, чтоб перейти на новую ветку.
И все одной только функцией, которая уже произвела проход вперед? Эт ты хватил - сделать возврат, ничего при этом не делая)) Ну ничего, уже вторая страничка закончилась, скоро Владимир не выдержит)))
Бог с ними, с этими страницами. Задача ведь интересная.
Понимаете, тут как можно.... Откат на узел родителя можно делать уже в новом вызове потомка. То есть при переходе на потомка система сначала опустится по дереву на уровень ниже, а потом поднимется в нового вызванного потомка.
Но в этом варианте нельзя сделать ветки с глубиной более двух. Так как система всегда будет возвращаться назад перед походом вперед. То есть все функции будут рисоваться на одном уровне.
Поэтому думается, что придется использовать какие-то массивы переменных, для идентификации текущего положения. чтоб идти дальше, а не возвращаться. Вот именно в этом возврате и сложность...
В прицепе "концептуальная заготовка", точнее пример реализации. на MT 5
Чтоб до ума довести нужно функции in() и out() переписать, дабы заставить работать со списком вызовов. Сейчас они тупо распечатывают входы и выходы в стандартный поток.
Плохая новость: Мечту топикстартера об одной трассировочной функции я не сберёг. Прости Сергеев. :)
Хорошая новость: Всё работает.
Руководство пользователя.
1. В начале каждой функции вставляется макрос "_in"
2. Все вызовы return заменяются на "_return"
3. В начале проги прописывается два дефайна
#define _in in(__FUNCTION__);
#define _return out(__FUNCTION__);return
Собсно всё.
Бог с ними, с этими страницами. Задача ведь интересная.
Понимаете, тут как можно.... Откат на узел родителя можно делать уже в новом вызове потомка. То есть при переходе на потомка система сначала опустится по дереву на уровень ниже, а потом поднимется в нового вызванного потомка.
Но в этом варианте нельзя сделать ветки с глубиной более двух. Так как система всегда будет возвращаться назад перед походом вперед. То есть все функции будут рисоваться на одном уровне.
Поэтому думается, что придется использовать какие-то массивы переменных, для идентификации текущего положения. чтоб идти дальше, а не возвращаться. Вот именно в этом возврате и сложность...