pmmp / Math

PHP library containing math related code used in PocketMine-MP
GNU Lesser General Public License v3.0
41 stars 20 forks source link

Using $x*$x is 2x faster than $x**2 #92

Closed AkmalFairuz closed 2 months ago

AkmalFairuz commented 3 months ago

Using $x**2

<?php
class Vector3 {
    public $x;
    public $y;
    public $z;

    public function __construct(float|int $x, float|int $y, float|int $z) {
        $this->x = $x;
        $this->y = $y;
        $this->z = $z;
    }

    public function distanceSquared(Vector3 $pos): float {
        return (($this->x - $pos->x) ** 2) + (($this->y - $pos->y) ** 2) + (($this->z - $pos->z) ** 2);
    }
}

$vector1 = new Vector3(1.0, 2.0, 3.0);
$vector2 = new Vector3(4.0, 5.0, 6.0);
$start = microtime(true);
for($i = 0; $i < 5000000; $i++){
  $res = $vector1->distanceSquared($vector2);
}
var_dump($res);
var_dump(microtime(true) - $start);
// output
// float(27)
// float(0.7717170715332031)

Using $x*$x

<?php
class Vector3 {
    public $x;
    public $y;
    public $z;

    public function __construct(float|int $x, float|int $y, float|int $z) {
        $this->x = $x;
        $this->y = $y;
        $this->z = $z;
    }

    public function distanceSquared(Vector3 $pos): float {
        $dx = $this->x - $pos->x;
        $dy = $this->y - $pos->y;
        $dz = $this->z - $pos->z;
        return ($dx * $dx) + ($dy * $dy) + ($dz * $dz);
    }
}

$vector1 = new Vector3(1.0, 2.0, 3.0);
$vector2 = new Vector3(4.0, 5.0, 6.0);
$start = microtime(true);
for($i = 0; $i < 5000000; $i++){
  $res = $vector1->distanceSquared($vector2);
}
var_dump($res);
var_dump(microtime(true) - $start);
// output
// float(27)
// float(0.5707399845123291)
dadodasyra commented 3 months ago

This is ridiculous but true (and more than 30%).

$x*2 0.6087791919708252 and $x$x 0.2943990230560303 With a Windows 11 php 8.2.11, i7-12700kf So more than 50%

AkmalFairuz commented 2 months ago

This is ridiculous but true (and more than 30%).

$x*2 0.6087791919708252 and $x$x 0.2943990230560303 With a Windows 11 php 8.2.11, i7-12700kf So more than 50%

That's 2x faster.

I also tested locally using an i5 10400F CPU, here are the results:

$x**2

float(27)
float(1.1193900108337402)

$x*$x

float(27)
float(0.5409140586853027)

It's really 2 times faster. $x**2 is often used in PM, especially in the Vector3->distanceSquared() method

SOF3 commented 2 months ago

I have no opposition to this, just noting that distanceSquared doesn't seem to be a hot path.