Dear all, being both a Unity3d and a Monkey (language! lol) lover I just made a quick test regarding 2d performance of both and would like to share the numbers:
I’ve used 2000 sprites which move randomly over the screen. Results are:
Unity 4.5
APK size: 8,404,358 bytes
FPS: ~20
Monkey v79c
APK size: 67,331 bytes
FPS: ~33 (previously I did a wrong fps calculation)
Unity C# code:
using UnityEngine;
using System.Collections;
public class Sprites : MonoBehaviour
{
public GameObject _sprite;
private ArrayList _spriteList;
// Use this for initialization
void Start()
{
_spriteList = new ArrayList();
for( int i = 0; i < 2000; i++ )
{
GameObject sprite = (GameObject)Instantiate( _sprite, new Vector3( Random.Range( -6.0f, 6.0f ), Random.Range( -4.0f, 4.0f ) ), Quaternion.identity );
_spriteList.Add( sprite );
}
}
// Update is called once per frame
void Update()
{
for( int i = 0; i < _spriteList.Count; i++ )
{
GameObject s = (GameObject)_spriteList[i];
Vector3 position = s.transform.position;
float deltaTime = Time.deltaTime;
position += new Vector3( Random.Range( -5.0f, 5.0f ), Random.Range( -5.0f, 5.0f ) ) * deltaTime;
position.x = Mathf.Clamp( position.x, -6.0f, 6.0f );
position.y = Mathf.Clamp( position.y, -4.0f, 4.0f );
s.transform.position = position;
}
}
}
Monkey code:
Strict
Import mojo
Function Main:Int()
New Game()
Return 0
End Function
Class Sprite
Field _img:Image
Field _x:Float
Field _y:Float
Method New( img:Image, x:Float, y:Float )
_img = img
_x = x
_y = y
End Method
End Class
Class Game Extends App
Field _sprite:Image
Field _spriteList:List<Sprite>
Field _resX:Float
Field _resY:Float
'FPS stuff
Field _previousTime:Int
Field _currentTime:Int
Field _passedTime:Int
Field _loopTimeAll:Int
Field _fpsCounter:Int
Field _fpsLastUpdate:Int
Field _fps:Float
Method OnCreate:Int()
_sprite = LoadImage( "sprite.png" )
_spriteList = New List<Sprite>
_resX = Float( DeviceWidth() )
_resY = Float( DeviceHeight() )
For Local i:Int = 0 Until 2000
Local s:Sprite = New Sprite( _sprite, Rnd( 0, _resX ), Rnd( 0, _resY ) )
_spriteList.AddLast( s )
Next
_currentTime = Millisecs()
SetUpdateRate(60)
Return 0
End Method
Method OnUpdate:Int()
Return 0
End Method
Method OnRender:Int()
_previousTime = _currentTime
_currentTime = Millisecs()
_passedTime = _currentTime - _previousTime
Cls()
For Local s:Sprite = EachIn _spriteList
Local dx:Float = Rnd( -0.1, 0.1 ) * _passedTime
Local dy:Float = Rnd( -0.1, 0.1 ) * _passedTime
s._x += dx
s._y += dy
s._x = Clamp( s._x, 0.0, _resX )
s._y = Clamp( s._y, 0.0, _resY )
DrawImage( s._img, s._x, s._y )
Next
DrawText( _fps + " FPS", 10, 10 )
updateFPS()
Return 0
End Method
Method OnSuspend:Int()
Return 0
End Method
Method OnResume:Int()
Return 0
End Method
Method updateFPS:Void()
_loopTimeAll += _passedTime
_fpsCounter += 1
If( ( _currentTime - _fpsLastUpdate ) > 500 )
Local renderTime:Float = Float( _loopTimeAll ) / Float( _fpsCounter )
If( renderTime < 1.0 ) Then renderTime = 1.0
_loopTimeAll = 0
_fpsLastUpdate = _currentTime
_fps = 1000.0 / renderTime
_fpsCounter = 0
End If
End Method
End Class
Sample APKs:
Unity: http://www.leidel.net/dl/monkey/2dtest/unitytest.apk
Monkey: http://www.leidel.net/dl/monkey/2dtest/monkeytest.apk
Project files:
http://www.leidel.net/dl/monkey/2dtest/unityproject.zip
http://www.leidel.net/dl/monkey/2dtest/monkeyproject.zip
Test device was a Sony Xperia S. I’d be interested in more comparison values and stuff how (especially) the Unity code could be done better? Have I done something terribly stupid in my Unity code?