Оптимизировать код рисования видов - PullRequest
1 голос
/ 26 мая 2010

в простом приложении для рисования У меня есть модель, в которой NSMutableArray curvedPaths содержит все линии, которые нарисовал пользователь. Сама линия также является NSMutableArray, содержащей точечные объекты. Когда я рисую кривые NSBezier пути, мой массив точек имеет следующую структуру: linePoint, controlPoint, controlPoint, linePoint, controlPoint, controlPoint и т. Д. Я думал, что один массив, содержащий все точки плюс контрольные точки, будет более эффективным, чем работа с 2 или 3 различными массивами.

Очевидно, что мое представление рисует пути, которые оно получает из модели, что приводит к актуальному вопросу: есть ли способ оптимизировать следующий код (внутри метода drawRect представления) с точки зрения скорости?

int lineCount = [[model curvedPaths] count];

// Go through paths
for (int i=0; i < lineCount; i++)
{
    // Get the Color
    NSColor *theColor = [model getColorOfPath:[[model curvedPaths] objectAtIndex:i]];

    // Get the points
    NSArray *thePoints = [model getPointsOfPath:[[model curvedPaths] objectAtIndex:i]];

    // Create a new path for performance reasons
    NSBezierPath *path = [[NSBezierPath alloc] init];

    // Set the color
    [theColor set];

    // Move to first point without drawing
    [path moveToPoint:[[thePoints objectAtIndex:0] myNSPoint]];

    int pointCount = [thePoints count] - 3;

    // Go through points
    for (int j=0; j < pointCount; j+=3)
    {
        [path curveToPoint:[[thePoints objectAtIndex:j+3] myNSPoint] 
             controlPoint1:[[thePoints objectAtIndex:j+1] myNSPoint]
             controlPoint2:[[thePoints objectAtIndex:j+2] myNSPoint]];
    }

    // Draw the path
    [path stroke];

    // Bye stuff
    [path release];
    [theColor release];
}

Спасибо, xonic

1 Ответ

4 голосов
/ 26 мая 2010

Привет xon1c, код выглядит хорошо. В целом, невозможно оптимизировать без измерения производительности в конкретных случаях.

Например, предположим, что приведенный выше код вызывается только один раз. Он рисует картинку в виде и не нуждается в перерисовке. Скажем, приведенный выше код занимает 50 миллисекунд для запуска. Вы можете переписать его в openGL и выполнить каждую оптимизацию под солнцем, и сократить это время до 20 миллисекунд, а реально сэкономленные 30 миллисекунд не будут иметь никакого значения ни для кого, и вы просто потратили свое время и добавили массу кода раздувание, которое будет труднее поддерживать.

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

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

Каждый раз, когда вы рисуете, вы воссоздаете NSBezierPaths - они всегда разные? Возможно, вы захотите сохранить список путей NSBezier для рисования, синхронизировать его с вашей моделью и сохранять рисование только для рисования путей.

Вы рисуете в тех областях вашего вида, которые не нуждаются в перерисовке? Аргумент для рисования - это область представления, которую необходимо перерисовать - вы можете проверить это (или getRectsBeingDrawn: count :), но в вашем случае вы знаете, что необходимо перерисовать все представление.

Если сами пути не меняются часто, но вид нужно часто перерисовывать - например, когда формы путей не меняются, но их положение анимируется и они перекрываются по-разному, вы можете нарисовать пути к изображениям (текстуры), а затем внутри drawrect вы бы нарисовали текстуру к виду вместо того, чтобы рисовать путь к виду. Это может быть быстрее, потому что текстура создается только один раз и загружается в видеопамять, которая быстрее выводится на экран. Вы должны взглянуть на Core Animation , если это то, что вам нужно сделать.

Если вы обнаружите, что рисование путей слишком медленное, вы можете посмотреть на CGPath

Так что, в целом, это действительно зависит от того, что вы делаете. Лучший совет, как и всегда, не увлекаться преждевременной оптимизацией. Если ваше приложение на самом деле не слишком медленное для ваших пользователей, ваш код просто в порядке.

...