crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

7 страниц V  « < 4 5 6 7 >  
Ответить в данную темуНачать новую тему
> Реализация анализатора (парсера) формул времени выполнения
AntonTatu
  опции профиля:
сообщение 10.3.2009, 12:49
Сообщение #51


Студент
*

Группа: Участник
Сообщений: 48
Регистрация: 27.11.2008
Пользователь №: 437

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(BRE @ 9.3.2009, 20:46) *
..получил увеличение производительности больше чем в 12 раз.


А что нужно сделать что бы переделать
Вот этот кусочек

f.addOp( new VarOp( &arr[ 0 ][ 4 ] ) );
f.addOp( new VarOp( &arr[ 3 ][ 7 ] ) );
f.addOp( new VarOp( &arr[ 7 ][ 1 ] ) );


на
на такой

f.addOp( new VarOp( &arr[ 0 ][ j ] ) );
f.addOp( new VarOp( &arr[ 3 ][ j ] ) );
f.addOp( new VarOp( &arr[ 7 ][ j ] ) );



т.е. необходимо создать формулу, посчитать ее,
j=0;
f.addOp( new VarOp( &arr[ 0 ][ j ] ) );
f.addOp( new VarOp( &arr[ 3 ][ j ] ) );
f.addOp( new VarOp( &arr[ 7 ][ j ] ) );
res = f.calc();
передвинуться на следующий j -й столбец массива arr, посчитать,
j : =j+1;
res = f.calc();
на следующий..
j : =j+1;
res = f.calc();
и т.д.

т.е. что бы появилась возможность "сдвигать" формулу и, не перестраивая формулу заново и не генерируя новый массив ?

Сообщение отредактировал AntonTatu - 10.3.2009, 17:36
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 10.3.2009, 20:21
Сообщение #52


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(BRE @ 9.3.2009, 20:46) *
Посмотрел.
QStack построен на базе QVector, и при добавлении/удалении элемента постоянно делает resize вектора.
std::stack построен на std::deque, соответственно скорость добавления/удаления на высоте.


Хорошо бы троллям спидтест запостить, а то не хорошо получается.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 10.3.2009, 20:24
Сообщение #53


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(SABROG @ 10.3.2009, 23:21) *
Хорошо бы троллям спидтест запостить, а то не хорошо получается.
отпишись, и тестовый примерчик приложи, как я понял у тебя он уже есть
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 10.3.2009, 20:29
Сообщение #54


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(Litkevich Yuriy @ 10.3.2009, 20:24) *
Цитата(SABROG @ 10.3.2009, 23:21) *
Хорошо бы троллям спидтест запостить, а то не хорошо получается.
отпишись, и тестовый примерчик приложи, как я понял у тебя он уже есть

Мопед не мой я просто разместил объяву :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 10.3.2009, 20:46
Сообщение #55


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(AntonTatu @ 10.3.2009, 12:49) *
т.е. что бы появилась возможность "сдвигать" формулу и, не перестраивая формулу заново и не генерируя новый массив ?

Ну барин ты задачки задаешь. (с) :)

Переделать операцию VarOp или сделать еще одну операцию (это набросок).
class VectorVarOp : public Oparation
{
public:
    VectorVarOp( const Vector &vec );

    void    run();
    void    setIndex( int i, int j );

private:
    Vector    &m_vector;
    int         m_i;
    int         m_j;
};

VectorVarOp::VectorVarOp( const Vector &vec )
    : m_vector( vec ), m_i( 0 ), m_j( 0 )
{
}

void VectorVarOp::run()
{
    m_stack.push( m_vector[ m_i ][ m_j ] );
}

void VectorVarOp::setIndex( int i, int j )
{
    m_i = i;
    m_j = j;
}

Таким образом можно наделать разных необходимых операций, ввести переменные и т.д.
Например, если у всех переменных необходимо изменять j, можно сделать такую операцию, которая это будет делать вызовом одной функции.
Думай пробуй. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AntonTatu
  опции профиля:
сообщение 10.3.2009, 23:38
Сообщение #56


Студент
*

Группа: Участник
Сообщений: 48
Регистрация: 27.11.2008
Пользователь №: 437

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(BRE @ 10.3.2009, 20:46) *
Ну барин ты задачки задаешь. (с) :)
.............................................
.............................................
Таким образом можно наделать разных необходимых операций, ввести переменные и т.д.
Например, если у всех переменных необходимо изменять j, можно сделать такую операцию, которая это будет делать вызовом одной функции.
Думай пробуй. :)


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

void AddOp::run()
{
    int v1 = m_stack.pop();
    int v2 = m_stack.pop();
    m_stack.push( v1 + v2 );
}

double Formula::calc() const
{
    // Выполнить все операции
    for( ListOp::ConstIterator iOp = m_ops.begin(); iOp != m_ops.end(); ++iOp ){
        (*iOp)->run();
    }
    // После выполнения на вершине арифметического стека результат
    return Operation::m_stack.pop();


как сделать так что бы при сложении если на стеке ( m_stack.push( v1 + v2 );) число больше ну к примеру 100 (или любого какое нравится) остановить подсчет Formula::calc() и вывести результат ?
я сделал так....
вот


//изменил этот класс так 
class Operation
{
public:
    virtual void  run() = 0;    //выполнить операцию
    virtual bool  exit() = 0;   //добавил проверку на выход

//изменил этот класс так
class VarOp : public Operation
{
public:
    VarOp( int *var  );

    void    run();
    bool    exit();

//изменил этот класс так
class AddOp : public Operation
{
public:
    void    run();
    bool    exit();
    bool flag;

//...............................................
void AddOp::run()
{
    int v1 = m_stack.pop();
    int v2 = m_stack.pop();
    m_stack.push( v1 + v2 );
    if (v1 >= 1) flag = false;
}


bool AddOp::exit()
{
   if (flag == false)
   {
       return false;
   }else
   {
    return true;
   }
}

//изменил этот класс так
double Formula::calc() const
{
    // Выполнить все операции
    for( ListOp::ConstIterator iOp = m_ops.begin(); iOp != m_ops.end(); ++iOp ){
        (*iOp)->run();
        if (!(*iOp)->exit()) {
            break;


все работает как надо, но мне кажется что можно было както проще сделать ?

Сообщение отредактировал AntonTatu - 11.3.2009, 0:21
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 11.3.2009, 6:12
Сообщение #57


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Мне кажется, что логичней, если сам метод run() будет сообщать нужно ли продолжать вычисления.

вот


class Operation
{
public:
    virtual bool  run() = 0;    //выполнить операцию, вернуть false - если необходимо прервать операцию
};

class VarOp : public Operation
{
public:
    VarOp( int *var  );

    bool    run();
};

class AddOp : public Operation
{
public:
    bool    run();
};

class DivOp : public Operation
{
public:
    bool    run();
};

//...............................................
void AddOp::run()
{
    int v1 = m_stack.pop();
    int v2 = m_stack.pop();
    m_stack.push( v1 + v2 );
    if (v1 >= 1) return false;

        return true;
}

// В операции деления проверяем, а не делим ли мы на 0!!!
void DivOp::run()
{
    int v1 = m_stack.pop();
        // Проверяем деление на 0!!!
        if( v1 == 0 )
                 return false;

    int v2 = m_stack.pop();
    m_stack.push( v2 / v1 );
    return true;
}

//изменил этот класс так
double Formula::calc() const
{
    // Выполнить все операции
    for( ListOp::ConstIterator iOp = m_ops.begin(); iOp != m_ops.end(); ++iOp )
        if( !(*iOp)->run() )
            break;
}


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

Можно ввести такое понятие как контекст, в котором хранить арифметический стек, состояние (ошибка), исходные данные, локальные переменные.
Тогда мы бы избавились от статического стека и получили возможность пихать расчет формул по разным потокам.

Если будут еще вопросы задавай, мне самому интересен этот вопрос. :)

Сообщение отредактировал BRE - 11.3.2009, 8:39
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AntonTatu
  опции профиля:
сообщение 11.3.2009, 11:09
Сообщение #58


Студент
*

Группа: Участник
Сообщений: 48
Регистрация: 27.11.2008
Пользователь №: 437

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(BRE @ 11.3.2009, 6:12) *
Мне кажется, что логичней, если сам метод run() будет сообщать нужно ли продолжать вычисления.

Так и знал что можно было огород не городить......с флажком... :(
Цитата
Еще желательно ввести методы для очистки стека, т.к. при таком прерывании операции возможны случаи, когда в стеке останутся данные.

сделал так:
вот

void MathStack::clear()
{
   while (!m_stack.empty()){
       m_stack.pop(); //удаляем верхний элемент в стэке, который формально является последним элементом в контэйнере
     }

}

//и сюда добавил

double Formula::calc() const
{
    //Очищаем стэк перед новым расчетом
    Operation::m_stack.clear(); //хотя заметил что перед новым расчетом стэк всегда пуст, даже если предыдущий выход из цикла был по брэйку....,
                                             //наверно и очищать его не нужно.... и функция лишняя... ?

    // Выполнить все операции
    for( ListOp::ConstIterator iOp = m_ops.begin(); iOp != m_ops.end(); ++iOp ){
        (*iOp)->run();
        if (!(*iOp)->exit()) {
            break;

     //после выполнения на вершине арифметического стэка результат
     return Operation::m_stack.pop();


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

вот это очень интересно, т.к. скорости мне все равно хочется больше... (если компилировать dll ку с массивом получается намного быстре, только компилятор таскать за собой не получится...)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 11.3.2009, 11:31
Сообщение #59


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(AntonTatu @ 11.3.2009, 11:09) *
//Очищаем стэк перед новым расчетом
//хотя заметил что перед новым расчетом стэк всегда пуст, даже если предыдущий выход из цикла был по брэйку....,
//наверно и очищать его не нужно.... и функция лишняя... ?

Вот смотри формула:
100 200 300 400 0 / * + +

происходит ошибка: Деление на 0, в стеке:
100 200 300 400

Тут от формулы зависит.

Цитата(AntonTatu @ 11.3.2009, 11:09) *
вот это очень интересно, т.к. скорости мне все равно хочется больше... (если компилировать dll ку с массивом получается намного быстре, только компилятор таскать за собой не получится...)

С нативом даже не сравнивай, не расстраивай себя. Такой производительности не будет. ;)

Контексты набросаю чуть позже...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 11.3.2009, 21:44
Сообщение #60


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Добавил контексты.
Разбил по файлам.
Кратко документировал.
Проект в архиве.
Прикрепленные файлы
Прикрепленный файл  qformula.tar.gz ( 2,79 килобайт ) Кол-во скачиваний: 312
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

7 страниц V  « < 4 5 6 7 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


12 чел. читают эту тему (гостей: 12, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 30.1.2025, 2:10