Интересный факт.
От: Saddam Россия http://saddam.narod.ru
Дата: 21.09.02 16:15
Оценка:
Две программы. Обе заполняют в Excel 15 тысяч ячеек. Одна написана на MSVC 6.0 с использованием ATL.
Та часть, которая заполняет:

OleInitialize(NULL);
    _Application Excel;
    Workbooks WorkBooks;
    _Workbook book;
    Worksheets Sheets;
    _Worksheet Sheet;
    COleVariant Cell;
    CString SCell;
    if(!Excel.CreateDispatch("Excel.Application"))
        {
            AfxMessageBox("Couldn't start Excel.");
        }
        else
        {
            //Make Excel Visible and display a message
            Excel.SetVisible(TRUE);
            WorkBooks=Excel.GetWorkbooks(); 
            book=WorkBooks.Add(NOPARAM); 
            Sheets=book.GetWorksheets();
            Sheet=Sheets.GetItem(COleVariant((short)1));
            CTime start=CTime::GetCurrentTime();
            m_Start.SetWindowText(start.Format("%H:%M:%S"));
            for (char i='A'; i<'P';i++)
                for (short j=1;j<=1000;j++)
                {
                    SCell.Format("%c%i",i,j);
                    Cell=SCell;
                    ((Range)Sheet.GetRange(Cell,Cell)).SetValue(Cell);
                }
            CTime stop=CTime::GetCurrentTime();
            m_Stop.SetWindowText(stop.Format("%H:%M:%S"));
            m_Diff.SetWindowText((stop-start).Format("%H:%M:%S"));
        }
    OleUninitialize();

И вторая, написана на BCB 5.0 с использованием OLE-вызовов, примеров море в интернете, приводить не буду.
Так вот... ATL-вариант делает это за 1 минуту 15 секунд, а OLE за 47 секунд, хотя, даже Inprise утверждает, что ATL круче OLE в плане новизны и правильности. Может я что-то не так сделал?
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
Re: Интересный факт.
От: George Seryakov Россия  
Дата: 21.09.02 16:58
Оценка:
Здравствуйте Saddam, Вы писали:

S>Две программы. Обе заполняют в Excel 15 тысяч ячеек. Одна написана на MSVC 6.0 с использованием ATL.

...
S>И вторая, написана на BCB 5.0 с использованием OLE-вызовов, примеров море в интернете, приводить не буду.

Нет уж, покажи цикл. Заодно и узнаем, что такое ole-вызовы.

S>Так вот... ATL-вариант делает это за 1 минуту 15 секунд, а OLE за 47 секунд, хотя, даже Inprise утверждает, что ATL круче OLE в плане новизны и правильности. Может я что-то не так сделал?


Скорее всего делается вызов разных наборов методов. Типа в одном случае диспатч, а в другом — нет. Или ранж по-разному вычисляется.
GS
Re[2]: Интересный факт.
От: Saddam Россия http://saddam.narod.ru
Дата: 22.09.02 10:04
Оценка:
Здравствуйте George Seryakov, Вы писали:

S>>Две программы. Обе заполняют в Excel 15 тысяч ячеек. Одна написана на MSVC 6.0 с использованием ATL.

GS>...
S>>И вторая, написана на BCB 5.0 с использованием OLE-вызовов, примеров море в интернете, приводить не буду.

GS> Нет уж, покажи цикл. Заодно и узнаем, что такое ole-вызовы.


S>>Так вот... ATL-вариант делает это за 1 минуту 15 секунд, а OLE за 47 секунд, хотя, даже Inprise утверждает, что ATL круче OLE в плане новизны и правильности. Может я что-то не так сделал?


GS> Скорее всего делается вызов разных наборов методов. Типа в одном случае диспатч, а в другом — нет. Или ранж по-разному вычисляется.

Пожалуйста...
#define PS(param) PropertySet(param)
string XlsDocument::MakeAddr(int row,int col)
{
    string cell;
    char strrow[6];
    int i,j;
    col--;
    if (col<0 || col>229 || row & 0xFFFF0000) //230 равно адресу IV (последний столбец)
        return "A1";
    if (i=col/26)       //получаем первую букву столбца
    {
        j=col%26;       //вторая буква стобца
        cell+=char('A'-1 + i);
        cell+=char('A' + j);
    }
    else                //буква столбца состоит из одного символа
        cell+=char('A' + col);
    itoa(row,strrow,10);
    cell+=strrow;
    return cell;
}
 
void XlsDocument::WriteCell(const string &cell,const string &value)
{
    Doc.Exec(PS("Range") << cell.c_str() << value.c_str());
}

//---------------------------Главный цикл
   char tmp[32];
    for (int j=1;j<16;j++)
        for(int i=1;i<1001;i++)
        {
            itoa(j,tmp,10);
            MyDoc.WriteCell(i,j,tmp);
        }
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
Re[3]: Интересный факт.
От: IT Россия linq2db.com
Дата: 22.09.02 21:49
Оценка:
Здравствуйте Saddam, Вы писали:

S>
S>char tmp[32];
S>for (int j=1;j<16;j++)
S>    for(int i=1;i<1001;i++)
S>    {
S>        itoa(j,tmp,10);
S>        MyDoc.WriteCell(i,j,tmp);
S>    }
S>


А где определена WriteCell(int,int,char*) ?
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Интересный факт.
От: George Seryakov Россия  
Дата: 22.09.02 22:28
Оценка:
Здравствуйте IT, Вы писали:

IT>Здравствуйте Saddam, Вы писали:


S>>
S>>char tmp[32];
S>>for (int j=1;j<16;j++)
S>>    for(int i=1;i<1001;i++)
S>>    {
S>>        itoa(j,tmp,10);
S>>        MyDoc.WriteCell(i,j,tmp);
S>>    }
S>>


IT>А где определена WriteCell(int,int,char*) ?


Строкой выше. Итого имеем:

VC:
for (char i='A'; i<'P';i++)
  for (short j=1;j<=1000;j++)
  {
    ((Range)Sheet.GetRange("ячейка","ячейка")).SetValue("значение");
  }


BC:
  for (int j=1;j<16;j++)
    for(int i=1;i<1001;i++)
    {
      Doc.Exec(PropertySet("Range") << "ячейка" << "значение");
    }


У моего ёкселя метода Exec нет. Соответвенно, не ясно, в какой набор COM-вызовов выливается BC-шный код.
GS
Re[5]: Интересный факт.
От: IT Россия linq2db.com
Дата: 22.09.02 22:34
Оценка:
Здравствуйте George Seryakov, Вы писали:

IT>>А где определена WriteCell(int,int,char*) ?


GS>Строкой выше. Итого имеем:


Строкой выше идёт WriteCell(const string &cell,const string &value);
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Интересный факт.
От: Saddam Россия http://saddam.narod.ru
Дата: 23.09.02 06:12
Оценка:
Здравствуйте IT, Вы писали:

IT>Здравствуйте George Seryakov, Вы писали:


IT>>>А где определена WriteCell(int,int,char*) ?


GS>>Строкой выше. Итого имеем:


IT>Строкой выше идёт WriteCell(const string &cell,const string &value);

void XlsDocument::WriteCell(const int i, const int j,const string &value)
{
Doc.Exec(PS("Range") << MakeAddr(i,j).c_str() << value.c_str());
}
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
Re[5]: Интересный факт.
От: Saddam Россия http://saddam.narod.ru
Дата: 23.09.02 06:18
Оценка:
Здравствуйте George Seryakov, Вы писали:


GS>Строкой выше. Итого имеем:


GS>VC:

GS>
GS>for (char i='A'; i<'P';i++)
GS>  for (short j=1;j<=1000;j++)
GS>  {
GS>    ((Range)Sheet.GetRange("ячейка","ячейка")).SetValue("значение");
GS>  }
GS>


GS>BC:

GS>
GS>  for (int j=1;j<16;j++)
GS>    for(int i=1;i<1001;i++)
GS>    {
GS>      Doc.Exec(PropertySet("Range") << "ячейка" << "значение");
GS>    }
GS>


GS>У моего ёкселя метода Exec нет. Соответвенно, не ясно, в какой набор COM-вызовов выливается BC-шный код.

Тут OLE. Это в ATL — COM-вызовы.
Variant::Exec
____________________________________________________________________________________
Executes an OLE procedure, function, or a property Get or Set method.

Variant __fastcall Exec(AutoCmd& cmd, Integer lcid = LOCALE_SYSTEM_DEFAULT);

Description

Use Exec to call Automation methods. 

The cmd parameter is the wrapper class for the method on an interface that is assigned as the Variant’s value. Use this parameter to identify the method you want to call and to assign any parameter values.

The lcid parameter is ignored by Variant. The locale identifier used to interpret parameters is always LOCALE_SYSTEM_DEFAULT.
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
Re: Интересный факт.
От: Saddam Россия http://saddam.narod.ru
Дата: 23.09.02 12:39
Оценка:
Здравствуйте Saddam, Вы писали:

S>Две программы. Обе заполняют в Excel 15 тысяч ячеек. Одна написана на MSVC 6.0 с использованием ATL.

S>Та часть, которая заполняет:

Неужели OLE быстрее COM почти в полтора раза?
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
Re[6]: Интересный факт.
От: George Seryakov Россия  
Дата: 23.09.02 13:38
Оценка:
Здравствуйте Saddam, Вы писали:


GS>>У моего ёкселя метода Exec нет. Соответвенно, не ясно, в какой набор COM-вызовов выливается BC-шный код.


S>Тут OLE. Это в ATL — COM-вызовы.


Это не OLE, а библиотека поддержки COM в билдере. Метод Exec таки сводится к набору COM-вызовов, как и любой код, работающий с екселем через интерфейсы автоматизации. Настоящий OLE тоже.
GS
Re[7]: Интересный факт.
От: IT Россия linq2db.com
Дата: 23.09.02 23:55
Оценка:
Здравствуйте George Seryakov, Вы писали:

S>>Тут OLE. Это в ATL — COM-вызовы.


GS>Это не OLE, а библиотека поддержки COM в билдере. Метод Exec таки сводится к набору COM-вызовов, как и любой код, работающий с екселем через интерфейсы автоматизации. Настоящий OLE тоже.


Это чем-то смахивает на DDE...
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Интересный факт.
От: IT Россия linq2db.com
Дата: 24.09.02 00:05
Оценка:
Здравствуйте Saddam, Вы писали:

S>>Две программы. Обе заполняют в Excel 15 тысяч ячеек. Одна написана на MSVC 6.0 с использованием ATL.

S>>Та часть, которая заполняет:

S>Неужели OLE быстрее COM почти в полтора раза?


Дело скорее всего в том что в Билдере происходит один вызов сервера, а VC++ по честному делает два:

((Range)Sheet.GetRange(Cell,Cell)).SetValue(Cell);
              1                     2


Первый раз возвращается объект Range, второй раз ты ему устанавливаешь значение через SetValue. Так как в этом случае происходит межзадачный вызов, то замедление обязательно должно быть. Вообще оптимизация работы COM серверов во многом сводится в первую очередь к оптимизации вызовов. Например, хороших результатов можно добиться, если написать в Ворде макрос и вызвать его, взвалив на него тем самым основную часть работы.

Вызов Exec в Билдере происходит скорее всего через DDE и делается это один раз вместо двух как показано в примере выше. Отсюда и разница.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Интересный факт.
От: George Seryakov Россия  
Дата: 24.09.02 03:13
Оценка:
Здравствуйте IT, Вы писали:

IT>Вызов Exec в Билдере происходит скорее всего через DDE и


Может быть. А может — и IOleCommandTarget::Exec. Я б его тоже проверил, во всяком случае.

IT>делается это один раз вместо двух как показано в примере выше. Отсюда и разница.
GS
Re[4]: Интересный факт.
От: IT Россия linq2db.com
Дата: 24.09.02 03:17
Оценка:
Здравствуйте George Seryakov, Вы писали:

IT>>Вызов Exec в Билдере происходит скорее всего через DDE и


GS>Может быть. А может — и IOleCommandTarget::Exec. Я б его тоже проверил, во всяком случае.


О, точно, это он

IT>>делается это один раз вместо двух как показано в примере выше. Отсюда и разница.
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Интересный факт.
От: Saddam Россия http://saddam.narod.ru
Дата: 24.09.02 06:10
Оценка:
Здравствуйте George Seryakov, Вы писали:

GS>Здравствуйте Saddam, Вы писали:


GS>

GS>>>У моего ёкселя метода Exec нет. Соответвенно, не ясно, в какой набор COM-вызовов выливается BC-шный код.

S>>Тут OLE. Это в ATL — COM-вызовы.


GS>Это не OLE, а библиотека поддержки COM в билдере. Метод Exec таки сводится к набору COM-вызовов, как и любой код, работающий с екселем через интерфейсы автоматизации. Настоящий OLE тоже.

То есть по-твоему Хелп билдера врет?

Executes an OLE procedure, function, or a property Get or Set method.
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
Re[3]: Интересный факт.
От: Saddam Россия http://saddam.narod.ru
Дата: 24.09.02 10:13
Оценка:
Здравствуйте IT, Вы писали:

IT>Здравствуйте Saddam, Вы писали:


S>>>Две программы. Обе заполняют в Excel 15 тысяч ячеек. Одна написана на MSVC 6.0 с использованием ATL.

S>>>Та часть, которая заполняет:

S>>Неужели OLE быстрее COM почти в полтора раза?


IT>Дело скорее всего в том что в Билдере происходит один вызов сервера, а VC++ по честному делает два:


IT>
IT>((Range)Sheet.GetRange(Cell,Cell)).SetValue(Cell);
IT>              1                     2
IT>


IT>Первый раз возвращается объект Range, второй раз ты ему устанавливаешь значение через SetValue. Так как в этом случае происходит межзадачный вызов, то замедление обязательно должно быть. Вообще оптимизация работы COM серверов во многом сводится в первую очередь к оптимизации вызовов. Например, хороших результатов можно добиться, если написать в Ворде макрос и вызвать его, взвалив на него тем самым основную часть работы.


IT>Вызов Exec в Билдере происходит скорее всего через DDE и делается это один раз вместо двух как показано в примере выше. Отсюда и разница.

Я где-то читал, что при вызове методов OLE производится дополнительный вызов для определения типа передаваемого параметра. Ну, для того, чтобы OLEVariant передал то, что хочет сервер. Или это не так? В Interbase API все так и происходит с Variantom.
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
Re[8]: Интересный факт.
От: George Seryakov Россия  
Дата: 24.09.02 15:42
Оценка:
Здравствуйте Saddam, Вы писали:

S>>>Тут OLE. Это в ATL — COM-вызовы.


GS>>Это не OLE, а библиотека поддержки COM в билдере. Метод Exec таки сводится к набору COM-вызовов, как и любой код, работающий с екселем через интерфейсы автоматизации. Настоящий OLE тоже.

S>То есть по-твоему Хелп билдера врет?

S>
S>Executes an OLE procedure, function, or a property Get or Set method.
S>


Существуют два OLE: OLE1, основанный на DDE и OLE2, основанный на COM. Если твой хелп имеет в виду OLE1 (в чем я лично сомневаюсь, хотя и не исключаю), то внутри это работа с DDE. Иначе это OLE2 и реализована как набор вызовов COM.
GS
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.