closesSafePoint

JavaScript performance comparison

Test case created by ThinkingStiff

Preparation code

 
<script>
Benchmark.prototype.setup = function() {
        var X = 0, Y = 1,
            currentPoint = [5,5],
            proposedPoint = [5,6],
            forbiddenPoints = [[5,6],[6,6],[4,7],[5,9],[6,7],[4,8],[5,8]],
            map = {left:1,top:1,right:10,bottom:10};
       
        function closestSafePoint1( point )
        {
           
            var x = point[X], y = point[Y], safePoints = [];
           
            for( var left = x - 1, top = y - 1, right = x + 1, bottom = y + 1;
                 left <= map.left || top <= map.top || right <= map.right || bottom <= map.bottom;
                 left--, top--, right++, bottom++)
            {
               
                checkHorizontalPoints( safePoints, point, left, right, top );
                checkHorizontalPoints( safePoints, point, left, right, bottom );
                checkVerticalPoints( safePoints, point, top + 1, bottom - 1, left );
                checkVerticalPoints( safePoints, point, top + 1, bottom - 1, right );
               
                if( safePoints.length )
                {
                   
                    safePoints.sort( function( a, b ){ return a[1] - b[1] } );
                    return safePoints[0];
                   
                };
               
            };
           
            return point; //if we get here, no safe points; use original point
           
        };
       
        function checkHorizontalPoints( points, fromPoint, startX, endX, y )
        {
           
            for( var x = startX; x <= endX ; x++ )
            {
             
                var toPoint = [x, y];
               
                if( !isForbidden( toPoint ) && !isCurrent( toPoint) && onMap( toPoint ) )
                {
                   
                    points.push( [toPoint, distance( fromPoint, toPoint )] );
                   
                };
               
            };
               
        };
       
        function checkVerticalPoints( points, fromPoint, startY, endY, x )
        {
           
            for( var y = startY; y <= endY ; y++ )
            {
             
                var toPoint = [x, y];
               
                if( !isForbidden( toPoint ) && !isCurrent( toPoint) && onMap( toPoint ) )
                {
                   
                    points.push( [toPoint, distance( fromPoint, toPoint )] );
                   
                };
               
            };
                 
        };
       
        function isForbidden( point )
        {
       
            for( var index = 0; index < forbiddenPoints.length; index++ )
            {
               
                if( forbiddenPoints[index].toString() == point.toString() ) return true;
       
            };
           
        };
       
        function isCurrent( point )
        {
           
            return currentPoint.toString() == point.toString() ? true : false;
           
        };
       
        function onMap( point )
        {
         
            var x = point[X], y = point[Y];
            return x >= map.left && y >= map.top && x <= map.right && y <= map.bottom;
           
        };
       
        function distance( pointA, pointB )
        {
         
            var xDiff = ( pointA[X] - pointB[X] ),
                yDiff = ( pointA[Y] - pointB[Y] );
           
            return Math.sqrt( ( xDiff * xDiff ) + ( yDiff * yDiff ) );    
           
        };
   
   
   
   
   
   
   
   
        function closestSafePoint2( currentPoint, proposedPoint )
        {
           
            if( isForbidden( proposedPoint ) )
            {
               
                var x = proposedPoint[X], y = proposedPoint[Y], safePoints = [], closestPoint = [];
                     
                for( var left = x - 1, top = y - 1, right = x + 1, bottom = y + 1, level = 1;
                     left <= map.left || top <= map.top || right <= map.right || bottom <= map.bottom;
                     left--, top--, right++, bottom++, level++ )
                {
                   
                    closestPoint = checkHorizontalPoints( safePoints, proposedPoint, left, right, top, level );
                    closestPoint = closestPoint
                        || checkHorizontalPoints( safePoints, proposedPoint, left, right, bottom, level );
                    closestPoint = closestPoint
                        || checkVerticalPoints( safePoints, proposedPoint, top + 1, bottom - 1, left, level );
                    closestPoint = closestPoint
                        || checkVerticalPoints( safePoints, proposedPoint, top + 1, bottom - 1, right, level );
                   
                    if( closestPoint )
                    {    
                   
                        return closestPoint;
                       
                    }
                    else if( safePoints.length )
                    {
                       
                        safePoints.sort( function( a, b ){ return a[1] - b[1] } );
                        return safePoints[0][0];
                   
                    };
               
                };
               
                return currentPoint; //if no safe points, use currentPoint
           
            }
            else
            {
               
                return proposedPoint; //not forbidden, so use it
               
            };
   
        };
       
        function checkHorizontalPoints2( points, fromPoint, startX, endX, y, level )
        {
           
            for( var x = startX; x <= endX ; x++ )
            {
             
                var toPoint = [x, y];
               
                if( !isForbidden( toPoint ) && !isCurrent( toPoint) && onMap( toPoint ) )
                {
                   
                    var distance = distanceBetween( fromPoint, toPoint );
   
                    if( distance == level )
                    {
                       
                        return toPoint;
                           
                    }
                    else
                    {
                       
                        points.push( [toPoint, distance] );
                       
                    };
                   
                };
               
            };
               
        };
       
        function checkVerticalPoints2( points, fromPoint, startY, endY, x, level )
        {
           
            for( var y = startY; y <= endY ; y++ )
            {
             
                var toPoint = [x, y];
               
                if( !isForbidden( toPoint ) && !isCurrent( toPoint) && onMap( toPoint ) )
                {
                   
                    var distance = distanceBetween( fromPoint, toPoint );
                   
                    if( distance == level )
                    {
                       
                        return toPoint;
                           
                    }
                    else
                    {
                       
                        points.push( [toPoint, distance] );
                       
                    };
                   
                };
               
            };
                 
        };
       
        function distanceBetween( pointA, pointB )
        {
         
            var xDiff = ( pointA[X] - pointB[X] ),
                yDiff = ( pointA[Y] - pointB[Y] );
           
            return Math.sqrt( ( xDiff * xDiff ) + ( yDiff * yDiff ) );    
           
        };
   
};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
closestSafePoint()
var point = closestSafePoint1( proposedPoint );
pending…
closestSafePoint() 2
var point = closestSafePoint2( currentPoint, proposedPoint );
pending…

You can edit these tests or add even more tests to this page by appending /edit to the URL.

Compare results of other browsers

0 comments

Add a comment