I just converted the only graphics oriented program I have ever written from carbon to cocoa. The carbon version was first written back in the FutureBasic days and converted to RealBasic shortly after it came out. I am finding that now that it is in Cocoa it almost 7 times slower and am wondering if someone far more knowledgable in this sort of thing can give me an idea of how to speed it up. Yes, the Carbon version did all of its work painting on to the Canvas from outside of the paint event. That has been corrected to make Cocoa happy.
The program shows the inner workings of 12 different sort algorithms with each element of the array being sorted shown as a bar on a canvas. Before the sort is started a picture object is filled with the proper background color and then the bars are painted from the random values that were placed in to the array. Canvas1.Refresh is then called and its paint event simply does a DrawPicture onto the canvas. Then as the sorting algorithm executes any time the need to move a bar, or pair of bars, either the drawOneBar or doSwap methods are called and the do the redrawing of the respective bar or bars.
The animation works, and I am happy that I got it that far; but, it sure seems that I should be able to get it to work better than what it is. I just tested the speed of the Carbon version versus the Cocoa version and got this.
To sort 251 bars in Carbon it was 19.6 seconds and in Cocoa it was 136.9 seconds, almost 7 times slower. And this was running Quick sort, the fastest of the sorts. I shudder to think the time it would take for the maximum number of bars the program can work with and the slowest sorting algorithm. Any suggestions on how to improve this? This old timer is in need of some help on this one. I am going to take a guess that it is the fact that the entire picture is being redrawn for every bar being moved and the program is running on a 27 inch screen with the canvas occupying nearly the whole screen. Still, the old carbon version with same sized canvas is seven times faster but it is only redrawing the bars as they move.
The following shows the four blocks of code that have anything to do with the animation. The comments at the top of all but the Canvas1.Paint event explains their function. In the drawOneBar method, if I change the canvas1.Refresh to canvas1.Invalidate I get no animation since the sorting algorithms do not relinquish time for the canvas to be updated.
[code]DrawBars
// This method is invoked any time the canvas needs to be redrawn with the bars in their
// original random order. So it is called as window opens, and then before the starrt of any
// sort routine. Also called any time barwidth or space between bars is changed since the number of
// bars will be changed. Last point it is called is if the user selects the New Bars option from the menu
Dim xPos, yPos, inc, i as Int32
#pragma BackgroundTasks False
#pragma BoundsChecking False
// Clear the canvas back to one solid color
sortPic.Graphics.foreColor = bkgndColor
sortPic.Graphics.fillRect 2, 2, canvas1.width - 2, canvas1.height - 2
//Draw border around the canvas where the bars will appear
sortPic.Graphics.foreColor = RGB(204, 0, 0)
sortPic.Graphics.drawline 1, 1, canvas1.width, 1 // top border
sortPic.Graphics.drawline 1, 1, 1, canvas1.height - 1 //left border
sortPic.Graphics.drawline canvas1.width - 1, 1, canvas1.width - 1, canvas1.height - 1 // right border
sortPic.Graphics.drawline 1, canvas1.height - 1, canvas1.width - 1, canvas1.height - 1 // bottom border
//Draw the bars
sortPic.Graphics.foreColor = barColor
xPos = 3
inc = barWidth + spaceBetweenBars
For i = 1 to gMaxBars
yPos = Canvas1.height - 1 - barsToSort(i)
sortPic.Graphics.fillRect xPos, yPos, barWidth, barsToSort(i)
xPos = xPos + inc
Next
Canvas1.Refresh
End Subroutine
doSwap(bar1 As Int32, bar2 As Int32)
// This method is called from the various sorting methods any time two bars need to be swapped.
// The element numbers in the array for the two bars are passed as arguments
// There are certain sort algorithms that bypass this method and call drawOneBar directly due
// to the logic within that algorithm. Quick, Merge, and Insertion sorts do this in certain cases
Dim temp as Int32
#pragma BackgroundTasks False
#pragma BoundsChecking False
// Swapping values in the i and j cells of the barsToSort array
temp = barsToSort(bar1)
barsToSort(bar1) = barsToSort(bar2)
barsToSort(bar2) = temp
numberOfSwaps = numberOfSwaps + 1 // boost swap count for this sort
if doAnimation then // bypass if no animation running
drawOneBar(bar1) // redraw first bar
drawOneBar(bar2) // redraw the second bar
end if
End Subroutine
drawOneBar(theBar As Int32)
// This method redraws one bar the needs to be moved during the sorting process.
// The element number of the array pertaining to the bar is passed as the argument
Dim inc, xPos, yPos, yPosFull as Int32
#pragma BackgroundTasks False
#pragma BoundsChecking False
if doAnimation then // bypass if no animation running
inc = barWidth + spaceBetweenBars // width of bar and spacing
xPos = 3 + (theBar - 1) * inc // x pos for this bar
yPos = Canvas1.height - 1 - maxBarHeight // y pos for max bar height
yPosFull = yPos
sortPic.Graphics.foreColor = bkgndColor // set to bg color
sortPic.Graphics.fillRect xPos, yPos, barWidth, maxBarHeight // blank out any old bar with background color
yPos = Canvas1.height - 1 - barsToSort(theBar) // y position for new bar height
sortPic.Graphics.foreColor = barColor
sortPic.Graphics.fillRect xPos, yPos, barWidth, barsToSort(theBar) // draw new bar
//canvas1.Invalidate // NO ANIMATION if this is used instead of Refresh
canvas1.Refresh // get canvas to reflect the change
end if
End Subroutine
Canvas1.Paint event
g.DrawPicture(sortPic, 0, 0)[/code]