Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Что быстрее FillRect?

8.2K
13 февраля 2006 года
TheMaster
32 / / 23.12.2005
Обратил внимание на низкую скорость работы моей программы. Запустил кое-какие функции из файлика <time.h>, шоб, значицца, посмотреть, какие строчки моей программы тратят больше всего времени на выполнение. Выяснил, что это - цикл. Логика работы следующая: есть двухмерный массив объектов некоторого типа, каждый одним из полей имеет логическое значение (true/false). Кроме того, есть Bitmap, который надо заполнить клеточками, чёрными либо белыми, в зависимости от логического значения. Берём двойной цикл и заполняем, с применением Bitmap->Canvas->FillRect. Всё пучком, всё работает, но - медленно. Не так давно (пару-тройку лет назад) баловался я с ассемблером, и понимаю, что такая проблема может быть на ассемблере решена за миллисекунды, но никак не за десятки и сотни этих миллисекунд, как мне говорят замеры времени. Слышал также краем уха, что операции с объектами TCanvas не отличаются особой торопливостью, и что есть методы написать гораздо более быстрые вещи. Может, кто-нибудь подскажет, как это можно сделать?
4.8K
13 февраля 2006 года
Jump
128 / / 09.11.2005
Не уверен, что так уж необходим асм...
Какой размер поля?
Какой размер квадратиков?
Какие цвета на поле, только черный и белый?
294
14 февраля 2006 года
Plisteron
982 / / 29.08.2003
Цитата:
Originally posted by TheMaster
Слышал также краем уха, что операции с объектами TCanvas не отличаются особой торопливостью, и что есть методы написать гораздо более быстрые вещи. Может, кто-нибудь подскажет, как это можно сделать?


TCanvas (и вообще любая высокоуровневая объектно-ориентированная библиотека) в любом случае медленнее, чем непосредственно API.
Попробуй сделать CreateBitmap() и рисовать на нём, а потом уже этот Bitmap выводить на экран.

8.2K
15 февраля 2006 года
TheMaster
32 / / 23.12.2005
Пробовал размер поля 200 на 200, квадратики 5 на 5, цвета чёрный и белый, но в моём цикле можно любой (в смысле, не знаю, как в пиксель один из двух цветов записать, притом, чтобы быстрее было, чем один из 16 миллионов). Процер VIA Cyrix III 800 (и не надо хи хи, мне и такой нравицца!!!), тратит на всё про всё то ли 50, то ли 80 мс. Ну, по моим прикидкам, даже 10 мс - и то много...
8.2K
15 февраля 2006 года
TheMaster
32 / / 23.12.2005
как доберусь домой - попробую...
294
17 февраля 2006 года
Plisteron
982 / / 29.08.2003
Цитата:
Originally posted by TheMaster
как доберусь домой - попробую...


Попробуешь -- обязательно поделись результатом!

4.8K
19 февраля 2006 года
Jump
128 / / 09.11.2005
Цитата:
Originally posted by Plisteron
TCanvas (и вообще любая высокоуровневая объектно-ориентированная библиотека) в любом случае медленнее, чем непосредственно API.
Попробуй сделать CreateBitmap() и рисовать на нём, а потом уже этот Bitmap выводить на экран.



Врядле на этом много сэкономишь...
Короче делать было вечером, делать было нечего, наваял код... :P
Для повторения эксперимента нужна голая формочка и на ней кнопочка, и на эту кнопочку вешаем все что ниже накалякано ;)

Код:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    //Инитиализ
    Bmp = new Graphics::TBitmap;
    //задаем формат
    Bmp->PixelFormat = pf1bit; //только черный и белый

    /*
    Картинка размеров 200*200 займет в памяти блок
    25*25 байт (200/8=25), каждый байт будет управлять
    сразу 8-ю пикселями. Дабы не иметь секса со стыками
    байтов, я бы рекомендовал размер
    квадратика сделать 8 пикселей - тогда "зачернив" один
    байт, зачернишь один квадратик. Так и сделаю.
    А далее через стреч нарисуем поле таким размером, как
    нам надо.
    Как я понял из условия поле 40*40 квадратов...
    */

    //задаем размер
    Bmp->Height = 320; //40*8
    Bmp->Width = 320;

    //Вспомогательный массив указателей на сканы строк
    char **Line = new char*[320];
    int i;
    for(i = 0; i<320; i++)
        Line = (char*)Bmp->ScanLine;

    //Инициализационная часть закончилась.
    //Работаем с изображением

    //И засечем время
    int t = GetTickCount();

    //Для наглядности закрашиваем черным клетку (x,y)=(2,5)
    // 0 = черный квадрат
    // 255 = белый
    int x=2;
    int y=5;

    for(i = y*8;i<(y+1)*8;i++)
        Line[x] = 0;

    //И сечас нарисуем шахматы
    for(x=0;x<40;x+=2)
    for(y=0;y<40;y+=2)
        for(i = y*8;i<(y+1)*8;i++)
            Line[x] = 0;

    for(x=1;x<40;x+=2)
    for(y=1;y<40;y+=2)
        for(i = y*8;i<(y+1)*8;i++)
            Line[x] = 0;

    //И теперь еще белую клетку сделаем
    x=15;
    y=5;
    for(i = y*8;i<(y+1)*8;i++)
        Line[x] = 255;

    /*
    Рисование закончили, засекаем время, и
    отображаем в окошке наш шедевр ;)
    */
    Caption = "Время (мс)~"+IntToStr(GetTickCount()-t);
    Canvas->StretchDraw(Rect(50,50,250,250),Bmp);
    //удаляем
    delete Bmp;

    /*
    Собственно каждый раз создавать и удалять не следует.
    Инициализационную часть можно повесить на запуск проги,
    а убивать при закрытии. И не забываем перерисовывать, т.е.
    делать Canvas->StretchDraw(Rect(50,50,250,250),Bmp);
    на OnPaint'е формы.
    */

}
1
19 февраля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by Jump
Врядле на этом много сэкономишь...
Короче делать было вечером, делать было нечего, наваял код... :P


Что бы сэкономить - надо пользоваться АПИ, а не стандартными классами билдера.

406
19 февраля 2006 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by kot_
Что бы сэкономить - надо пользоваться АПИ, а не стандартными классами билдера.



Наиболее быстрый способ через Апи использовать Dib Section,например создав ее с помоью CreateDibSection или GetDIBits. Получаеш 2х мерный массив картинки и пишеш туда попиксельно. За остальным в MSDN. Или посмотри по форумам где упоминается данная функция.

246
20 февраля 2006 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by Jump
Врядле на этом много сэкономишь...
Короче делать было вечером, делать было нечего, наваял код... :P


Когда нечего делать будет попробуй поработать со свойством TCanvas::CopyMode.

4.8K
21 февраля 2006 года
Jump
128 / / 09.11.2005
Цитата:
Originally posted by kot_
Что бы сэкономить - надо пользоваться АПИ, а не стандартными классами билдера.



Однако классы билдера в данном случае - чисто надстройка над функциями ГДИ АПИ. И TBitmap в независимом от устройства режиме - это тотже DIB (по скорости разницы не заметил) (DIB - device independet bitmap - Тупо двумерный массив, лежащий в памяти видюхи, как и Canvas)
И между прочим (для тех, кто код ваще смотрел), я через клас ничего и не рисую.
Кстати, засечь по нормальному время ни кто не пробовал? У меня тиккоунт там все время 0 рисует :)

4.8K
21 февраля 2006 года
Jump
128 / / 09.11.2005
Цитата:
Originally posted by GIZMO
Когда нечего делать будет попробуй поработать со свойством TCanvas::CopyMode.


А поточней... Работать-то - работал...

4.8K
21 февраля 2006 года
Jump
128 / / 09.11.2005
Цитата:
Originally posted by Jump
Кстати, засечь по нормальному время ни кто не пробовал? У меня тиккоунт там все время 0 рисует :)


Короче сам засек :)
По PerformanceCounter'у время работы с изображением (непосредственно с Bmp'шкой, без учета выливания на окно) на моем 2.8 Гц проце ~ 0.00005 сек.

ЗЫ: "Вы не любите кошек? Вы просто не умеете их готовить!" :D :D :D

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог