Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 | 2 |

 

  Вопрос: Как быстрее ставить пикселы не используя DirectX Добавлено: 03.09.08 20:10  

Автор вопроса:  

Ответить

  Ответы Всего ответов: 27  

Номер ответа: 16
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #16 Добавлено: 10.09.08 10:11
Один ощутимый недостаток твоего кода - в нем создается 10 000 лишних объектов Graphics

Более того, эти объекты не удаляются а продолжают висеть в памяти после окончания работы, что само по себе не кооректно. И если ты читал хоть одну книгу по использованию GDI в NET ты должен был увидеть, что при работе с любыми графическими объектами (pen, brush и т.д.) исползование using является обязательным!

Ответить

Номер ответа: 17
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #17 Добавлено: 10.09.08 10:14
кто запрещает в вб6 подключить GDI+ ? Я в плюсах частенько рисую с GDI+ например, все достаточно шустро.

Да никто не запрещает, на здоровье! Только если на "Запорожец" поставить колеса от Бугатти Вейрон он все равно быстрее не поедет. И этот VB6 как был убожеством так и останется, что ты к нему не прикручивай. И сравнение C++ с VB6 в данном случае как минимум неуместно.

Ответить

Номер ответа: 18
Автор ответа:
 s12



Вопросов: 24
Ответов: 363
 Профиль | | #18 Добавлено: 10.09.08 10:55
Поищи, если интересно, был тут недавно challenge, так код на Vb6 "отсосал" у Vb .NET то ли в разы, то ли на порядки Вобщем весело было
Злыдень!
ИМХО тема плавно переходит в флуд. Мое мнение - нужна быстрая графика учи DirectX, или OpenGL (немного примитивнее, зато попроще), да - долго, да - нудно, но это единственные извесные мне способы почти полностью переложить обработку графики на видеокарту.

Ответить

Номер ответа: 19
Автор ответа:
 



Вопросов: 1
Ответов: 4
 Профиль | | #19 Добавлено: 10.09.08 11:17
Проверил я. Мои предположения о разнице на порядке, увы, оказались неверными. Но разница все равно есть и мой код выигрывает почти 20% (14 против 11 секунд).


То-есть ты хочеш сказать - что вставил тот код что я выложил, кинул две кнопки на форму и получил такие результаты?

Но я клянусь тебе - у меня оба кода в Debug работают одинаково! (кстати незнаю как реализовать измерение времени програмным методом - знаю что через timer будет некоректно, поэтому замерял секундомером - 12 сек.)
К слову не понятно что имеется в виду под "построением проекта"?

- Release я так понимаю - тоесть готовый .ехе файл.

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

а если накосячил - найди ошибку - код у тебя есть. (только комент там не к месту вставлен)

Ну а про потерю памяти - ну сейчас не в этом дело, а в том что у меня нет плюсов в скорости от using


Ответить

Номер ответа: 20
Автор ответа:
 Ra$cal



ICQ: 8068014 

Вопросов: 18
Ответов: 817
 Web-сайт: www.rascalspb.narod.ru
 Профиль | | #20
Добавлено: 10.09.08 14:56
стати незнаю как реализовать измерение времени програмным методом

Используй апи GetTickCount

  1. long start_time = GetTickCount();
  2. // много работы
  3. long work_time = GetTickCout() - start_time;


Время в миллисекундах.

Ответить

Номер ответа: 21
Автор ответа:
 



Вопросов: 1
Ответов: 4
 Профиль | | #21 Добавлено: 10.09.08 16:22
Ra$cal спасибо! (вообщето я и раньше видел подобное - с системным временем, только забыл))

А Stell Brand и Eros - объясните пожалуйсто следуйщее.
  1. Public Class Form1
  2.     Declare Function GetTickCount Lib "kernel32" () As Integer
  3.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  4.         Dim j, k As Integer
  5.         Dim start_time As Integer = GetTickCount()
  6.         Using gr = PictureBox1.CreateGraphics
  7.             For j = 0 To 100
  8.                 For k = 0 To 100
  9.                     gr.DrawLine(Pens.Black, k, j, k, j + 1)
  10.                 Next
  11.             Next
  12.         End Using
  13.         TextBox1.Text = GetTickCount() - start_time
  14.         start_time = GetTickCount()
  15.         For j = 0 To 100
  16.             For k = 0 To 100
  17.                 PictureBox1.CreateGraphics.DrawLine(Pens.Black, k, j, k, j + 1)
  18.             Next
  19.         Next
  20.         TextBox2.Text = GetTickCount() - start_time
  21.         TextBox3.Text = (TextBox1.Text - TextBox2.Text) / TextBox2.Text * 100
  22.     End Sub
  23. End Class

Согласно этому коду в Debug код с использованием using работает в среднем на 20% больше чем без ниего. В Release замедление и того больше - все 100%!!

Как все это понимать?

Stell Brand - ты точно проверял у себя?

Ответить

Номер ответа: 22
Автор ответа:
 fluke



ICQ: 318170731 

Вопросов: 15
Ответов: 96
 Профиль | | #22 Добавлено: 10.09.08 17:08
Тут надо не понимать, а явну указывать тип объекта, перед его юзаньем Using gr As Graphics = PictureBox1.CreateGraphics

Ответить

Номер ответа: 23
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #23 Добавлено: 11.09.08 01:12
А Stell Brand и Eros - объясните пожалуйсто следуйщее.

Объясняю:
1. Код в топку
2. Руки кривые
3. Твой секундомер сломаный
4. А за такой код
TextBox3.Text = (TextBox1.Text - TextBox2.Text) / TextBox2.Text * 100

вообще линчевать надо. Ты что нибудь о приведении типов слышал?

  1.  
  2. using System;
  3. using System.Drawing;
  4. using System.Windows.Forms;
  5.  
  6. namespace TestUsing
  7. {
  8.     public partial class Form1 : Form
  9.     {
  10.         public Form1()
  11.         {
  12.             InitializeComponent();
  13.             /* add handler */
  14.             btnStart.Click += new EventHandler(btnStart_Click);
  15.         }
  16.  
  17.         void btnStart_Click(object sender, EventArgs e)
  18.         {
  19.             string _userMessage = "====== Test #{0} ======\r\n";
  20.             _userMessage += "WITHOUT USING:\t{1}\r\n";
  21.             _userMessage += "WITH USING:\t\t{2}\r\n";
  22.             _userMessage += "RESULT:\t\t\t{3:F2}%\r\n";
  23.             _userMessage += "\r\n";
  24.  
  25.  
  26.             for (int i = 0; i < 5; i++)
  27.             {
  28.                 int result1, result2;
  29.                 int j, k;
  30.                                 
  31.                 /* without using */
  32.                 result1 = Environment.TickCount;
  33.                 for (j = 0; j < 100; j++)
  34.                 {
  35.                     for (k = 0; k < 100; k++)
  36.                     {
  37.                         pictureBox1.CreateGraphics().DrawLine(Pens.Black, k, j, k, j + 1);
  38.                     }
  39.                 }
  40.                 result1 = Environment.TickCount - result1;
  41.  
  42.                 /* with using */
  43.                 result2 = Environment.TickCount;
  44.                 using (Graphics graphics = pictureBox1.CreateGraphics())
  45.                 {
  46.                     for (j = 0; j < 100; j++)
  47.                     {
  48.                         for (k = 0; k < 100; k++)
  49.                         {
  50.                             graphics.DrawLine(Pens.Black, k, j, k, j + 1);
  51.                         }
  52.                     }
  53.                 }
  54.                 result2 = Environment.TickCount - result2;
  55.  
  56.                 /* show result */
  57.                 Console.WriteLine(_userMessage, i + 1, result1, result2,
  58.                                  (float)(result1 - result2) / result2 * 100);
  59.             }
  60.         }
  61.     }
  62. }



Результаты:
  1.  
  2. ====== Test #1 ======
  3. WITHOUT USING: 984
  4. WITH USING: 562
  5. RESULT: 75,09%
  6.  
  7.  
  8. ====== Test #2 ======
  9. WITHOUT USING: 1000
  10. WITH USING: 579
  11. RESULT: 72,71%
  12.  
  13.  
  14. ====== Test #3 ======
  15. WITHOUT USING: 968
  16. WITH USING: 594
  17. RESULT: 62,96%
  18.  
  19.  
  20. ====== Test #4 ======
  21. WITHOUT USING: 984
  22. WITH USING: 579
  23. RESULT: 69,95%
  24.  
  25.  
  26. ====== Test #5 ======
  27. WITHOUT USING: 1000
  28. WITH USING: 578
  29. RESULT: 73,01%



Как видишь использование using дает 70% выигрыш в скорости и не оставляет после себя мусора в памяти.

Ответить

Номер ответа: 24
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #24 Добавлено: 11.09.08 01:20
Сорри, с процентами наврал, но суть остается прежней..

Ответить

Номер ответа: 25
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #25 Добавлено: 12.09.08 07:58
То-есть ты хочеш сказать - что вставил тот код что я выложил, кинул две кнопки на форму и получил такие результаты?

Но я клянусь тебе - у меня оба кода в Debug работают одинаково! (кстати незнаю как реализовать измерение времени програмным методом - знаю что через timer будет некоректно, поэтому замерял секундомером - 12 сек.)


- Release я так понимаю - тоесть готовый .ехе файл.

И опять же клянусь - в .ехе файле код с использованием using работает медленне.., может тебе подойти к этому делу серьезнее и еще раз все проверить, потому как ну не мог я

Пойми, ты можешь клясться что у тебя Pentium Pro обгоняет Intel Xeon Quad на перемножении матриц, но даже это не отменяет законов физики и здравого смысла.

Ну а про потерю памяти - ну сейчас не в этом дело, а в том что у меня нет плюсов в скорости от using

Если бы ты почитал что такое Using и какой его смысл понял бы абсурдность своего заявления.

Using не должен давать никакого ускорения (теоритически) - единственная его задача - это обеспечить корректное освобождение неуправляемых ресурсов.

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

В данном случае основное различие между моим и твоим вариантом состоит в другом - я создаю один объект Graphics и использую его для отрисовки 10000 линий. Ты же создаешь 10000 таких объектов.



Я запускал не твой код, а писал свой.

Вот сейчас запустил твой код. Получаю результат:
Запуск в Debug
Мой вариант: 468
Твой вариант: 577

Запуск в Release
Мой вариант: 452
Твой вариант: 562

т.е. грубо говоря те же 20% что всплыли и у меня.
Откуда у тебя разница в обратную сторону появилась я не знаю

На всякий случай:
Windows server 2008 x64 (Windows AERO отключен)
Intel Core 2 Duo E6750 2.67 GHz
2 GB RAM
ATI Radeon X1600



Для замера производительности GetTickCount использовать не обязательно.
Во-первых, можно обойтись без АПИ, просто используя System.Environment.TickCount.

Я же лично использую следующую конструкцию для замера времени:

  1.         Dim start = Now
  2.         For i = 0 To 100000
  3.             Me.CreateGraphics.DrawLine(Pens.Black, 0, 0, 100, 100)
  4.         Next
  5.         Dim Length = Now.Subtract(start)
  6.         MessageBox.Show(Length.ToString)

И получается вывод:
00:00:15.0500094


цифре 0.0500094 конечно не стоит сильно доверять :) Скорее 94 микросекунды всплыли из-за ошибки округления. Бери первые 3 знака после запятой.



Что касается запуска в Debug/Release - разницы здесь практически не должно быть (и как видишь - практически и нет). Потому что основное время будет выполняться код самого .NET Framework и код GDI+.

Пержде всего.
В отличие от VB6, в котором отладка выполнялась в интерпретаоре, в .NET интерпретатора нет.

Когда ты запускаешь проект, выполняется сборка exe-файла. Далее он запускается и к нему подключается отладчик Visual Studio.

В чем же разница между сборкой в Debug/Release, запуском под отладчиком или без отладчика.
Она состоит в том что при сборке Debug в файл записывается отладочная информация, кроме того отключаются все возможные оптимизации компилятора. Делается это для того чтоб можно было провести полноценную отладку.
В сборке Release отладочная информация не записывается и включается оптимизатор. Полученный exe-файл теоритически работает быстрее чем Debug-версия.
Кстати, даже если ты делаешь Release сборку, но запускаешь проект под отладчиком, JIT-комплиятор все равно не будет проводить оптимизацию - для этого нужно либо "руками" запускать exe-файл, без Visual Studio, либо из Visual Studio запускать проект через Debug - Start without debugging (Ctrl+F5).

В том примере который рассматриваем мы оптимизировать, я думаю, практически нечего, поэтому разницы между запуском в Debug и Release практически нет (разница в 4% которую видим скорее всего свзана с тем что отладчик немного замедляет работу приложения).

Ответить

Номер ответа: 26
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #26 Добавлено: 12.09.08 08:03
Вот, забыл добавить.
Именно потому что в .NET проводится отладка скомпилированного exe-файла, в первых версиях .NET не было такой фичи как Edit & Continue, которая была в VB6. То есть, не было возможности приостановить выполнение программы, изменить кусок кода программы и продолжить выполнение.

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

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

Ответить

Номер ответа: 27
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #27 Добавлено: 12.09.08 08:06
Тут надо не понимать, а явну указывать тип объекта, перед его юзаньем Using gr As Graphics = PictureBox1.CreateGraphics

Зависит от версии. В VB .NET 9.0 указывать тип не нужно, там неявная типизация сработает.

В любом случае 10000 вызовов через Reflection не дадут двухкратное падение скорости, как утверждает некий пан без имени.

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам