Objective-C图形绘制速度

Objective-C图形绘制速度,objective-c,Objective C,我想一个像素一个像素地画到屏幕上。我有这个代码工作,但它很慢。。。我发现这非常奇怪,因为用javascript编写的同类代码速度非常快。速度足够快,我不得不放慢我的间隔,调用这个 我需要做什么才能将速度提高至少2到3倍 目标-c 我想CfNumberTargetValue正在处理intValue调用?我要做的第一件事是分析您的代码,看看是什么花了这么多时间。我猜这里花了很多时间: [[template objectAtIndex:y*8+x] intValue] 如果我的猜测是正确的,您应该能

我想一个像素一个像素地画到屏幕上。我有这个代码工作,但它很慢。。。我发现这非常奇怪,因为用javascript编写的同类代码速度非常快。速度足够快,我不得不放慢我的间隔,调用这个

我需要做什么才能将速度提高至少2到3倍

目标-c


我想CfNumberTargetValue正在处理intValue调用?

我要做的第一件事是分析您的代码,看看是什么花了这么多时间。我猜这里花了很多时间:

[[template objectAtIndex:y*8+x] intValue]
如果我的猜测是正确的,您应该能够通过将模板从NSArray切换到常规的C整数数组来提高速度

编辑:

现在我看到了个人资料,我想我的猜测是对的。你试过切换到C数组吗


如果您对渲染字体的不同方法持开放态度,请参见纹理图集,它可能会给您一些好的想法。

我要做的第一件事是分析您的代码,看看什么需要这么多时间。我猜这里花了很多时间:

[[template objectAtIndex:y*8+x] intValue]
如果我的猜测是正确的,您应该能够通过将模板从NSArray切换到常规的C整数数组来提高速度

编辑:

现在我看到了个人资料,我想我的猜测是对的。你试过切换到C数组吗


如果您对渲染字体的不同方法持开放态度,请参见纹理图集,它可能会给您一些好主意。

调用NSBezierPath的fillRect方法来绘制每个像素是疯狂的。如果你必须一次画一个像素,然后画进你自己的缓冲区,当它准备好显示时,你就把它发送到OSX的高度矢量化的硬件加速的基于OpenGL的图形系统中。如果您不打算利用Quartz提供的任何高级绘图原语,那么不要每帧调用Quartz一百万次。如果你不想自己实施闪电游戏,请使用SDL或Allegro。但是你应该考虑每一个字母是否需要逐像素绘制。OSX的图形系统非常擅长合成图像,因为这是它的主要用途。顺便问一下,为什么不能使用普通的文本呈现方法并将其绑定到自己的字体文件中呢

调用NSBezierPath的fillRect方法来绘制每个像素是疯狂的。如果你必须一次画一个像素,然后画进你自己的缓冲区,当它准备好显示时,你就把它发送到OSX的高度矢量化的硬件加速的基于OpenGL的图形系统中。如果您不打算利用Quartz提供的任何高级绘图原语,那么不要每帧调用Quartz一百万次。如果你不想自己实施闪电游戏,请使用SDL或Allegro。但是你应该考虑每一个字母是否需要逐像素绘制。OSX的图形系统非常擅长合成图像,因为这是它的主要用途。顺便问一下,为什么不能使用普通的文本呈现方法并将其绑定到自己的字体文件中呢

我非常同意这种画法是疯狂的。有可能有更好的方法来做到这一点。首先想到的是切换位图的各个像素,然后调用单个绑定纹理和单个绘制

假设您不会或无法更改此算法,从您的分析信息来看,您似乎在花费所有时间发送消息。我要做的第一件事是加速它,将它全部拉到一个丑陋的怪物方法中,而不是将它分成三个。是的,它既丑陋又愚蠢,但它将有效地照亮循环中发送的所有消息,并且只执行逻辑

编辑:

不带objc_messageSend的位图上下文绘图


我非常同意这种绘画方法是疯狂的。有可能有更好的方法来做到这一点。首先想到的是切换位图的各个像素,然后调用单个绑定纹理和单个绘制

假设您不会或无法更改此算法,从您的分析信息来看,您似乎在花费所有时间发送消息。我要做的第一件事是加速它,将它全部拉到一个丑陋的怪物方法中,而不是将它分成三个。是的,它既丑陋又愚蠢,但它将有效地照亮循环中发送的所有消息,并且只执行逻辑

编辑:

不带objc_messageSend的位图上下文绘图


我试过找精确的字体,但找不到。我发现的字体在显示时会失真,并且不是100%像素完美。为此,我宁愿不处理第三方LIB。我最初是在玩NSBitmapImageRep,直接更新数据而不是setPixel。这比这慢了100倍。在OSX中可以获得像素级的字体渲染。Proggy字体在终端和终端中都可以正常工作
其他应用程序。如果您找不到适合您需要的字体,请使用FontForge。@user57368您可以提供一个示例或链接,说明如何使用/捆绑自定义字体吗?我已经试着找到了确切的字体,但找不到。我发现的字体在显示时会失真,并且不是100%像素完美。为此,我宁愿不处理第三方LIB。我最初是在玩NSBitmapImageRep,直接更新数据而不是setPixel。这比这慢了100倍。在OSX中可以获得像素级的字体渲染。Proggy字体在终端和其他应用程序中运行良好。如果您找不到适合您需要的字体,请使用FontForge。@user57368能否提供一个示例或链接,说明如何使用/捆绑自定义字体?您是否有示例URL或教程或其他内容?我不介意把它改成更好的,但是就像我说的,我试着用一个NSBitmapImageRep来搞乱它,但是它慢了一些……我会试着找到一个很好的例子来说明我所说的,你有没有试着把它们合并成一个整体的方法而没有任何改进?你有没有一个示例URL或教程或其他什么?我不介意把它改成更好的,但就像我说的,我试着用NSBitmapImageRep来搞乱它,但它的速度较慢……我会尝试找到一个很好的例子来说明我所说的,你有没有尝试过将它们合并成一个整体的方法而没有任何改进?这是一篇关于使用calayer IMHO@slf制作纹理地图集的更好的文章。有趣的是,这篇文章如何链接到我发布的那篇文章。事实上,这就是我如何找到我的链接的。这确实加快了速度,但还不够。我将尝试user57368的方法。这是一篇关于使用calayer IMHO@slf制作纹理地图集的更好的文章。有趣的是,这篇文章链接到了我发布的那篇文章。事实上,这就是我找到链接的方式。这确实加快了速度,但还不够。我将尝试user57368的方法。我认为这是唯一加快当前算法速度的方法。
Running Time    Self        Symbol Name
12371.0ms   21.8%   12371.0     objc_msgSend
2612.0ms    4.6%    2612.0      CFNumberGetValue
2446.0ms    4.3%    2446.0      _class_getInstanceSize
1910.0ms    3.3%    1910.0      -[__NSArrayI objectAtIndex:]
1482.0ms    2.6%    1482.0      _CFExecutableLinkedOnOrAfter
1384.0ms    2.4%    1384.0      object_getIndexedIvars
1350.0ms    2.3%    1350.0      -[AnsiView drawCharater:atX:atY:color:]
1277.0ms    2.2%    1277.0      OSAtomicCompareAndSwap64Barrier$VARIANT$mp
1270.0ms    2.2%    1270.0      ripl_BltShape
1261.0ms    2.2%    1261.0      -[__NSCFNumber intValue]
1185.0ms    2.0%    1185.0      CFRelease
1047.0ms    1.8%    1047.0      CGSShmemGuardUnlock
1005.0ms    1.7%    1005.0      ripr_Rectangles
[[template objectAtIndex:y*8+x] intValue]
CGContextRef MyCreateBitmapContext (int pixelsWide,
                            int pixelsHigh)
{
    CGContextRef    context = NULL;
    CGColorSpaceRef colorSpace;
    void *          bitmapData;
    int             bitmapByteCount;
    int             bitmapBytesPerRow;

    bitmapBytesPerRow   = (pixelsWide * 4);// 1
    bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);

    colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);// 2
    bitmapData = calloc( bitmapByteCount );// 3
    if (bitmapData == NULL)
    {
        fprintf (stderr, "Memory not allocated!");
        return NULL;
    }
    context = CGBitmapContextCreate (bitmapData,// 4
                                    pixelsWide,
                                    pixelsHigh,
                                    8,      // bits per component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaPremultipliedLast);
    if (context== NULL)
    {
        free (bitmapData);// 5
        fprintf (stderr, "Context not created!");
        return NULL;
    }
    CGColorSpaceRelease( colorSpace );// 6

    return context;// 7
}

void DrawMyStuff()
{
    CGRect myBoundingBox;// 1

    myBoundingBox = CGRectMake (0, 0, myWidth, myHeight);// 2
    myBitmapContext = MyCreateBitmapContext (400, 300);// 3
    // ********** Your drawing code here ********** // 4
    CGContextSetRGBFillColor (myBitmapContext, 1, 0, 0, 1);
    CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 200, 100 ));
    CGContextSetRGBFillColor (myBitmapContext, 0, 0, 1, .5);
    CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 100, 200 ));
    myImage = CGBitmapContextCreateImage (myBitmapContext);// 5
    CGContextDrawImage(myContext, myBoundingBox, myImage);// 6
    char *bitmapData = CGBitmapContextGetData(myBitmapContext); // 7
    CGContextRelease (myBitmapContext);// 8
    if (bitmapData) free(bitmapData); // 9
    CGImageRelease(myImage);
}