Array Performance

51 views
Skip to first unread message

ihsan ciftci

unread,
Oct 24, 2011, 10:54:31 AM10/24/11
to Google Web Toolkit
Hi.

My drawing operation was too slow with respect to Java.
I observed the code. So I get Canvas is faster than Graphics2D with AA
on.
But what was that slowness?

Many times, I'm creating a point object with several methods. The
creation of those objects were much slower than java.

I deleted the unnecessary methods. Then I reduced the problem as
follows:

CODE BEGIN
<code>

public class MGPoint
{
public double[] coor;

public MGPoint(double x, double y ) {
coor = new double[2];
coor[0] = x;
coor[1] = y;
}

public double getX()
{
return coor[0];
}


public double getY()
{
return coor[1];
}

public int getDimension()
{
return coor.length;
}

public void setCoordinates(double x, double y)
{
coor[0] = x;
coor[1] = y;
}

}


public class MGPoint2
{
public double x;
public double y;

public MGPoint2(double x, double y ) {
this.x = x;
this.y = y;
}

public double getX()
{
x;
}


public double getY()
{
y;
}

public int getDimension()
{
return 2;
}

public void setCoordinates(double x, double y)
{
this.x = x;
this.y = y;
}

}


public class Performance implements EntryPoint
{
public void onModuleLoad()
{
final TextBox box = new TextBox();
box.setText("100000");

final Button button = new Button("");
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event)
{
int times = Integer.parseInt(box.getText());
Duration d = new Duration();
double z = 0;
for(int i = 0; i < times; i++)
{
MGPoint point = new MGPoint(26,45);
double x = point.getX();
double y = point.getY();
int dimension = point.getDimension();
z = x + y + dimension;
}
int time = d.elapsedMillis();

button.setText(time + "::::" + z) ;
}

});

final Button button2 = new Button("");
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event)
{
int times = Integer.parseInt(box.getText());
Duration d = new Duration();
double z = 0;
for(int i = 0; i < times; i++)
{
MGPoint2 point = new MGPoint2(26,45);
double x = point.getX();
double y = point.getY();
int dimension = point.getDimension();
z = x + y + dimension;
}
int time = d.elapsedMillis();

button2.setText(time + "::::" + z) ;
}

});

RootPanel.get().add(box);
RootPanel.get().add(button1);
RootPanel.get().add(button2);
}
}

</code>
CODE END


The x,y approach takes 2 ms in chrome, 10 ms in firefox.
The double array approach takes 200 ms in chrome, 400 ms in firefox.

Java (Development mode) does below 4 ms in both case.

Is it GWT specific?
What are your suggestions? How can I decrease the time?




Thomas Broyer

unread,
Oct 24, 2011, 12:21:48 PM10/24/11
to google-we...@googlegroups.com
Are you compiling with -XdisableCastChecking? That might make a difference.

ihsan ciftci

unread,
Oct 24, 2011, 4:42:57 PM10/24/11
to Google Web Toolkit
No effect.

ihsan ciftci

unread,
Oct 25, 2011, 4:56:18 AM10/25/11
to Google Web Toolkit
I wrote JS equivalent of my test case in 4 ways.

function mgpoint1(x,y)
{
this.x = x;
this.y = y;
this.getX = function()
{
return this.x;
}

this.getY = function()
{
return this.y;
}
this.getDimension = function()
{
return 2;
}
this.setCoordinates = function(x,y)
{
this.x = x;
this.y = y;
}
}

mgpoint2 is array version of mgpoint1.
mgpoint3 is prototype version of mgpoin1.
mgpoint4 is prototype version of mgpoint2.


function mgpoint3(x,y)
{
this.x = x;
this.y = y;
}

mgpoint3.prototype.getX = function()
{
return this.x;
}

mgpoint3.prototype.getY = function()
{
return this.y;
}
mgpoint3.prototype.getDimension = function()
{
return 2;
}
mgpoint3.prototype.setCoordinates = function(x,y)
{
this.x = x;
this.y = y;
}

The test code is

var i;
var z = 0;
for(i=0; i < 1000000; ++i )
{
var point = new mgpoint1(26,45);
var x = point.getX();
var y = point.getY();
var dimension = point.getDimension();
z = x + y + dimension;
}

Then I wrote another case for simple optimization in js.

function mgpoint5()
{
this.x = 26;
this.y = 45;
}

var i, x, y, point;
var z = 0;
for(i=0; i < 1000000; ++i )
{
point = new mgpoint5();
x = point.x;
y = point.y;
z = x + y + 2;
}



My results are a bit strange.
1 million times
(Chrome 14 results)
JS X-Y: mgpoint1 : 1021
JS Array: mgpoint2 : 1061
Proto X-Y: mgpoint3 : 310
Proto Array: mgpoint4 : 356
Optimized X-Y: mgpoint5 : 308

GWT X-Y: MGPoint2 : 31
GWT Array: MGPoint : 2327


1 million times
(Firefox 5 results)
JS X-Y: mgpoint1 : 1499
JS Array: mgpoint2 : 1732
Proto X-Y: mgpoint3 : 1166
Proto Array: mgpoint4 : 1379
Optimized X-Y: mgpoint5: 455

GWT X-Y: MGPoint2 : 342
GWT Array: MGPoint : 5613

Thomas Broyer

unread,
Oct 25, 2011, 6:09:14 AM10/25/11
to google-we...@googlegroups.com
Compile in -style PRETTY to see how GWT compiles your Java code down to JS. There won't be getX/getY (they'll be inlined), at least in the x,y case (and if there are, they'll be "staticified": getX(point) instead of point.getX()). And you'll probably see type coercion/checking in the array case (and if that's the case, as I suspect, it's what causes the difference in performance between your two implementations).

ihsan ciftci

unread,
Oct 25, 2011, 8:01:27 AM10/25/11
to Google Web Toolkit
I forgot to mention the for loop invariant.

By test results are according to

var times = document.getElementById("times").value;
//Began capturing time
for(i=0; i < times; ++i)
{
...
}

I have converted it to

var times = parseInt(document.getElementById("times").value);
//Began capturing time
for(i=0; i < times; ++i)
{
...
}


So the results are:


My results are a bit strange.
1 million times
(Chrome 14 results)
JS X-Y: mgpoint1 : 645
JS Array: mgpoint2 : 718
Proto X-Y: mgpoint3 : 37
Proto Array: mgpoint4 : 56
Optimized X-Y: mgpoint5 : 23
GWT X-Y: MGPoint2 : 31
GWT Array: MGPoint : 2461

1 million times
(Firefox 5 results)
JS X-Y: mgpoint1 : 414
JS Array: mgpoint2 : 576
Proto X-Y: mgpoint3 : 120
Proto Array: mgpoint4 : 204
Optimized X-Y: mgpoint5: 114
GWT X-Y: MGPoint2 : 137
GWT Array: MGPoint : 4014


-XdisableCastChecking resulted with no change.
Reply all
Reply to author
Forward
0 new messages