Правильный способ сократить код с помощью множества приведений и очевидных шаблонов в C #

1

Итак, у меня есть приложение, которое рисует на экране. Я работаю с двойниками, но для рисования я должен использовать float или ints. Итак, такие вещи случаются часто:

g.DrawEllipse(monsterPen, new Rectangle(
  (int)Math.Round(x - (double)sizeVessel * 9.0 / 20.0), 
  (int)Math.Round(y - (double)sizeVessel * 9.0 / 20.0), 
  (int)Math.Round(sizeVessel * 18.0 / 20.0),
  (int)Math.Round(sizeVessel * 18.0 / 20.0)));

Хотя это может выглядеть так

g.DrawEllipse(monsterPen, NewRectangleFromD(
  x - (double)sizeVessel * 9.0 / 20.0),
  y - (double)sizeVessel * 9.0 / 20.0),
  sizeVessel * 18.0 / 20.0,
  sizeVessel * 18.0 / 20.0)));

Или даже как это

DrawCircle(g, monsterPen, x, y, sizeVessel * 9.0 / 20.0)

Однако я не уверен, как лучше это делать.

В C/C++, если моя память мне хорошо помогает, вы можете сделать псевдоним, сказав, что, например, этот код:

DrawCircle(g, p, x, y, r) 

должен быть предназначен для всех целей:

g.DrawEllipse(p, new Rectangle(
  (int)Math.Round(x - r / 2.0), 
  (int)Math.Round(y - r / 2.0), 
  (int)Math.Round(r), 
  (int)Math.Round(r))

Но я не могу найти такой вариант в С#. Без возможности принудительного inline (я работаю в.Net 4.0). Я боюсь, что если я просто объявлю метод DrawCircle, который сделает это, я замедлю свое приложение (эти призывы вызова выполняются довольно часто).

Итак, каков правильный подход?

  • 1
    Сделать метод расширения?
  • 0
    @DavidG DavidG, но нет ли у него дополнительных затрат? Если я использую метод расширения, будет ли стек вызовов выглядеть следующим образом: (main -> call DrawCircle -> call DrawEllipse) или как этот (main -> call DrawEllipse)?
Показать ещё 14 комментариев
Теги:

2 ответа

4
Лучший ответ

Один из вариантов заключается в использовании методов расширения:

public static class GraphicsExtentions
{
    public static void DrawEllipse(this Graphics g, Pen pen, double x, double y, double width, double height)
    {
        g.DrawEllipse(pen, (int)x, (int)y, (int)width, (int)height);
    }
}

Что вы называете так:

double x, y, w, h;
...
g.DrawEllipse(pen, x, y, w, h);

И если вы хотите, чтобы это было очень быстро, вы могли бы посмотреть на агрессивный атрибут inlining:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void DrawEllipse(this Graphics g, Pen pen, double x, double y, double width, double height)
{
    g.DrawEllipse(pen, (int)x, (int)y, (int)width, (int)height);
}
  • 0
    Спасибо. Как я ответил выше, я ищу бесплатное решение, потому что в этом случае оно, очевидно, достижимо ...
  • 0
    Как вы думаете, почему это «очевидно достижимо»?
Показать ещё 5 комментариев
1

Я отвечу здесь, чтобы указать, почему вы не должны беспокоиться об этом.

Вы используете GDI+, который является программным рендерером. В любом случае интенсивная графика с этой библиотекой будет очень медленной.

Сколько циклов процессора необходимо для вызова функции? И сколько нужно, чтобы нарисовать эллипс в программном обеспечении? У меня нет цифр, но я уверен в одном: они будут на несколько порядков.

Вывод: здесь вы пытаетесь оптимизировать неправильную вещь. Если вы хотите быстро отображать графику, используйте аппаратное ускоренное решение.

  • 0
    Я понимаю, что использую медленный метод, когда рассматриваемое решение было запущено, я не знал, как использовать OpenGl или SDL для вывода примитивов, и теперь потребуется огромное усилие для переноса всего. Я думаю, вы правы, что относительное влияние будет незначительным, я просто не хочу добавлять дополнительные издержки, если смогу помочь
  • 0
    @Istrebitel Моя точка зрения, вы, кажется, недооцениваете, насколько незначительным является воздействие. Даже Math.Round , который вы вызываете 4 раза, будет иметь гораздо больше накладных расходов, чем еще один кадр стека.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню