Here's the source for my benchmarking app: bench.zip (8.3 KB)
runs at 50fps by default
edit: 2020-12-19, added
edit: 2020-10-27, added
- fSpriteSetImage,
- fSpriteSetCenterStatic,
- fSpriteSetCenterToggle,
- fSpriteSetCenterRandom,
Code improvements accepted!
import "CoreLibs/graphics"
import "CoreLibs/sprites"
import "CoreLibs/timer"
local gfx <const> = playdate.graphics
local format <const> = string.format
local wait <const> = playdate.wait
local update <const> = playdate.graphics.sprite.update
local updateTimers <const> = playdate.timer.updateTimers
local cos <const> = math.cos
local sin <const> = math.sin
local floor <const> = math.floor
local random <const> = math.random
local drawLine <const> = playdate.graphics.drawLine
local wait <const> = playdate.wait
local drawText <const> = playdate.graphics.drawText
local drawTextInRect <const> = playdate.graphics.drawTextInRect
local drawRect <const> = playdate.graphics.drawRect
local fillRect <const> = playdate.graphics.fillRect
local drawCircleAtPoint <const> = playdate.graphics.drawCircleAtPoint
local fillCircleAtPoint <const> = playdate.graphics.fillCircleAtPoint
local drawCircleInRect <const> = playdate.graphics.drawCircleInRect
local fillCircleInRect <const> = playdate.graphics.fillCircleInRect
local lockFocus <const> = playdate.graphics.lockFocus
local unlockFocus <const> = playdate.graphics.unlockFocus
local pushContext <const> = playdate.graphics.pushContext
local popContext <const> = playdate.graphics.popContext
local now = playdate.getCurrentTimeMilliseconds
math.randomseed(0) -- same random numbers every time
local function rnd(x)
return random(0,x)
end
local playerSprite = nil
local FPS = 50
local frameMS = 1000/FPS
playdate.display.setRefreshRate(FPS)
if playdate.isSimulator then
location = "SIMULATOR"
else
location = "DEVICE"
end
local W <const> = playdate.display.getWidth()
local H <const> = playdate.display.getHeight()
local CW <const> = W/2
local CH <const> = H/2
local start = 0
local count = 0
local cmd = 1
local runs = 5
local cmdName = ""
local done = false
local testImage <const> = gfx.image.new( "Images/background" )
local testBack = gfx.image.new( "Images/background" )
local testSprite <const> = gfx.image.new("Images/playerImage")
local function fNil() end
local function fDrawLineDiagonal() drawLine(0, 0, W, H) return "drawLine - Diagonal" end
local function fDrawLineHorizontal() drawLine(0, CH, W, CH) return "drawLine - Horizontal" end
local function fDrawLineVertical() drawLine(CW, 0, CW, H) return "drawLine - Vertical" end
local function fDrawLineRandomDiagonal() drawLine(0, rnd(H), W, rnd(H)) return "drawLine - Random Diagonal" end
local function fDrawLineFillRect() fillRect(0, CH, W, 1) return "drawLine - fillRect" end
local function fDrawLineDrawRect() drawRect(0, CH, W, 1) return "drawLine - drawRect" end
local function fMathRandom() math.random(0,999) return "math.random" end
local function fMathRandomLocal() random(0,999) return "math.random - local" end
local function fMathSin() sin(90) return "math.sin" end
local function fMathSinRandom() sin(rnd(359)) return "math.sin - random" end
local function fMathCos() cos(90) return "math.cos" end
local function fMathCosRandom() cos(rnd(359)) return "math.cos - random" end
local function fMathFloor() floor(1.23) return "math.floor - local" end
local function fImageSample() testImage:sample(0, 0) return "image:sample" end
local function fDrawText() drawText("TEST!", CW-22, CH+50) return "drawText - local" end
local function fDrawTextInRect() drawTextInRect("TEST!", CW-25, CH+50, 50, 50, nil, nil, kTextAlignment.center) return "drawTextInRect" end
local function fDrawRect() drawRect(CW-50, CH-50, 100, 100) return "drawRect" end
local function fFillRect() fillRect(CW-50, CH-50, 100, 100) return "fillRect" end
local function fDrawCircleAtPoint() drawCircleAtPoint(CW, CH, 100) return "drawCircleAtPoint" end
local function fFillCircleAtPoint() fillCircleAtPoint(CW, CH, 100) return "fillCircleAtPoint" end
local function fDrawCircleInRect() drawCircleInRect(CW-50, CH-50, 100, 100) return "drawCircleInRect" end
local function fFillCircleInRect() fillCircleInRect(CW-50, CH-50, 100, 100) return "fillCircleInRect" end
local function fSpriteMoveToStatic() playerSprite:setVisible(true) playerSprite:moveTo(CW, CH) return "sprite:moveTo - static" end
local function fSpriteMoveToRandom() playerSprite:setVisible(true) playerSprite:moveTo(rnd(W), rnd(H)) return "sprite:moveTo - random" end
local function fSpriteSetImage() playerSprite:setImage( testSprite ) return "sprite:setImage" end
local function fSpriteSetCenterStatic() playerSprite:setCenter(0, 0) return "sprite:setCenter - static" end
local function fSpriteSetCenterToggle() playerSprite:setCenter(playerSprite.x and 400 or 0, 0) return "sprite:setCenter - toggle" end
local function fSpriteSetCenterRandom() playerSprite:setCenter(rnd(399), 0) return "sprite:setCenter - random" end
local function fSpriteSetZIndex() playerSprite:setZIndex(1) return "sprite:setZIndex" end
local function fDraw() testSprite:draw(0,0) return "image:draw" end
local function fDrawLocked() gfx.lockFocus(testBack) testSprite:draw(0,0) gfx.unlockFocus() return "image:draw - locked" end
local function fDrawLockedLocal() lockFocus(testBack) testSprite:draw(0,0) unlockFocus() return "image:draw - locked local" end
local function fDrawPushContext() pushContext(testBack) testSprite:draw(0,0) popContext() return "image:draw - pushcontext local" end
-- local function () return "" end
funcs = {
fNil,
fDrawLineDiagonal,
fDrawLineHorizontal,
fDrawLineVertical,
fDrawLineRandomDiagonal,
fDrawLineFillRect,
fDrawLineDrawRect,
fMathRandom,
fMathRandomLocal,
fMathSin,
fMathSinRandom,
fMathCos,
fMathCosRandom,
fMathFloor,
fImageSample,
fDrawText,
fDrawTextInRect,
fDrawRect,
fFillRect,
fDrawCircleAtPoint,
fFillCircleAtPoint,
fDrawCircleInRect,
fFillCircleInRect,
fSpriteMoveToStatic,
fSpriteMoveToRandom,
fSpriteSetImage,
fSpriteSetCenterStatic,
fSpriteSetCenterToggle,
fSpriteSetCenterRandom,
fSpriteSetZIndex,
fDraw,
fDrawLocked,
fDrawLockedLocal,
fDrawPushContext,
}
local max = #funcs
function myGameSetUp()
local playerImage = gfx.image.new("Images/playerImage")
assert( playerImage ) -- make sure the image was where we thought
playerSprite = gfx.sprite.new()
playerSprite:setImage( playerImage )
playerSprite:setCenter( 0.5, 0.5 )
playerSprite:moveTo( CW, CH )
playerSprite:setVisible(false)
playerSprite:add() -- This is critical!
local backgroundImage = gfx.image.new( "Images/background" )
assert( backgroundImage )
lockFocus(backgroundImage)
playdate.graphics.drawTextInRect("*BENCH*", CW-50, CH-7, 100, 50, nil, nil, kTextAlignment.center)
unlockFocus(backgroundImage)
gfx.sprite.setBackgroundDrawingCallback(
function( x, y, width, height )
gfx.setClipRect( x, y, width, height ) -- just draw what we need
backgroundImage:draw( 0, 0 )
gfx.clearClipRect()
end
)
end
myGameSetUp()
function playdate.gameWillResume()
cmd = 1
start = 0
wait(300)
end
function playdate.update()
-- playdate.graphics.sprite.update()
-- playdate.timer.updateTimers()
update()
updateTimers()
if start == 0 then
start = now()
end
if cmd == 1 then
print(location.." ("..runs.." RUN AVE)\n")
print("#,"," BENCH,","CALL")
end
-- run command for a frame worth of milliseconds
if start > 0 and cmd > 0 and cmd <= max then -- approx calls: 104000 sim, 3000 device
for i = 1,runs do
while now() < start+frameMS do
cmdName = funcs[cmd]()
count = count + 1
end
start = now()
end
done = true
end
if done == true then
print(format("%02d,\t%6d,", cmd, count//runs), cmdName)
done = false
count = 0
start = 0
cmd = cmd + 1
end
if cmd == max+1 then
print("\nEND")
cmd = cmd + 1
playerSprite:setVisible(false)
playdate.display.setRefreshRate(30)
end
end