What Is the Overhead of Using PHP Int

What is the overhead of using PHP int?

I need more space than a comment to expand on mario's findings so I'll add an answer instead.

The size of a C union will be the size of its largest member (possibly with extra bytes to satisfy alignment constraints). For zvalue_value, that would be the obj which has the size of three pointers (not including the memory required for what those pointers point to):

typedef struct _zend_object {
zend_class_entry *ce;
HashTable *properties;
HashTable *guards; /* protects from __get/__set ... recursion */
} zend_object;

On a 32bit system, a zend_object will take 24 bytes while on a 64bit system it will take 48 bytes. So, every zvalue_value will take at least 24 or 48 bytes regardless of what data you store in it. There's also the name of the variable which consumes more memory; compiled languages generally discard the names once the compiler is done and treat values as simple sequences of bytes (so a double takes eight bytes, a char takes one byte, etc...).

With regards to your recent questions about PHP booleans, a simple boolean value will consume 24 or 48 bytes for the value, plus a few more bytes for the name, plus four or eight for the zend_unit, plus four (or eight) for the two zend_uchars in this:

struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};

The zend_uchar members will chew up four (or eight) bytes due to alignment constraints, almost every CPU wants to access memory on natural address boundaries and that means that a single byte sized member of a struct will take up four bytes or eight bytes of memory (depending on the CPUs natural word size and alignment constraints). So, a boolean will take somewhere between 36 and 72 bytes of memory.

How much memory does a variable with int value require in PHP?

So, thanks to Sergiu Paraschiv's comment, I installed memprof and made a small research on the topic. Here is what I got on my Mac with PHP 5.5.18 (64-bit):

<?php
memprof_enable();

$a = 255; // +104 (+32 for smth initial?), total: 136
$b = 255; // +104, total: 240
$c = 255.5; // +104, total: 344
$d = 'h'; // +104, total: 448
$e = []; // +176, total: 624
$f = new stdClass; // +136, total: 760
$g = $f; // +72, total: 832
$h = $g; // +72, total: 904
$i = $a; // +72, total: 976
$j = &$i; // +104, total: 1080
$k = &$j; // +72, total: 1152 why not 104?
$l = &$h; // +104, total: 1256
$m = null; // +104, total: 1360
$n = true; // +104, total: 1464

print_r(memprof_dump_array());

Array (
[memory_size] => 1464
[blocks_count] => 27
[memory_size_inclusive] => 1464
[blocks_count_inclusive] => 27
[calls] => 1
[called_functions] => Array
(
[memprof_dump_array] => Array
(
[memory_size] => 0
[blocks_count] => 0
[memory_size_inclusive] => 0
[blocks_count_inclusive] => 0
[calls] => 1
[called_functions] => Array
(
)

)

)
)

mySQL UPDATE TEXT vs INT field types (speed performance)

It probably won't make a significant difference in performance whether you store a serialized array or multiple columns, unless you have very high traffic and long strings.

The cases where it would make any measurable difference are when your array is so long that the serialized string doesn't fit on a single database page. InnoDB automatically finds extra page(s) to store the remainder of the string, but that means more page loads, more disk seeks, etc. To avoid overflow pages, the serialized string would have to be 768 bytes or less (see Blob Storage in Innodb for full explanation of this).

Another consideration is when you have a very long string and you need to post the whole string just to update a single member of the array. Those bytes have to travel across the network somehow, and there's no way to post only a substring when you use the serialized-array approach. The longer your strings, the more overhead there is to doing an UPDATE. Eventually if you have a lot of these updates executing concurrently, you could use up all your network bandwidth.

For example, a gigabite network (1000Mbit/s) has a throughput of about 112 MB/s. If your strings average 100KB, and you have 1125 concurrent updates per second, that's all of your bandwidth, even on a fast, dedicated network. That doesn't even count other traffic on the same network.


Re your comment and update:

Sounds like the number of updates and the average string length are quite modest. Not great enough for this to be a bottleneck. If you connect using the loopback TCP/IP interface (127.0.0.1) then you don't have to worry about bandwidth.

PHP Constants: Advantages/Disadvantages

The performance difference will be negligible unless you're storing a lot of them.
I'd write the toString() method more concisely:

$strings = array
(
self::USER_TYPE_ADMIN => 'admin',
self::USER_TYPE_USER => 'user',
);

if (!isset($strings[$type]))
return 'unknown';

return $strings[$type];

Also, you could make the $strings array a static.

In PDO is there a difference in performance if a int is quoted as a string?

If you want to take it exactly the method where you specify the type is slightly faster than where you not specify the type and the default type is PDO::PARAM_STR.

If you run it 1 million time the avarage is as followed:

  • int type specified: 0.53 seconds ($stmt->bindValue(":param", 5, PDO::PARAM_INT);)
  • no type specified: 0.66 seconds ($stmt->bindValue(":param", 5);)
  • str type sepcified: 0.70 seconds ($stmt->bindValue(":param", 5, PDO::PARAM_STR);)

Tested with PHP version 5.6.3; 32bit Windows;

PHP performance of using constants instead of strings

You can test it with something like below.

Note that PHP Optimizes a lot, and stores compiled byte code in its cache.
http://php.net/manual/en/intro.opcache.php

The results

string
0.38328790664673
constant
0.50211310386658

string
0.38391804695129
constant
0.51568698883057

What surprises me is that String seems to be faster.

I noted the following setting in the opcache config:

opcache.interned_strings_buffer integer
The amount of memory used to store interned strings, in megabytes.
This configuration directive is ignored in PHP < 5.3.0.

A pretty neat setting with like 0 documentation. PHP uses a technique called string interning to improve performance so, for example, if you have the string "foobar" 1000 times in your code, internally PHP will store 1 immutable variable for this string and just use a pointer to it for the other 999 times you use it. Cool. This setting takes it to the next level. instead of having a pool of these immutable string for each SINGLE php-fpm process, this setting shares it across ALL of your php-fpm processes. It saves memory and improves performance, especially in big applications.

So stating that string comparison is slower than constant comparison is a wrong assumption in PHP.

BUT: You can break this optimalization example:

$state = "State";
switch($string) {
case "Offline" . $state:
break;
}

The result of this will be:
string 0.61401081085205 constant 0.51961803436279

In this case the constant comparison will be faster.

The performance improvements where added to PHP5.4 and here is the RFC
https://wiki.php.net/rfc/performanceimprovements

But note that constants generally make for better refactor able code and therefor better maintainable. Furthermore the performance hit is negligible

function doSomethingString() {
return "OfflineState";
}

const OFFLINE_STATE = 1;
function doSomethingConstant() {
return OFFLINE_STATE;
}

function dummy() {}

// String
echo('string' . PHP_EOL);
$start = microtime(true);
for($i = 0; $i < 10000000; $i++) {
switch(doSomethingString()) {
case "OfflineState":
dummy();
break;
}
}
echo(PHP_EOL);
$end = microtime(true);
echo($end - $start);
echo(PHP_EOL);

//Constant
echo('constant' . PHP_EOL);
$start = microtime(true);
for($i = 0; $i < 10000000; $i++) {
switch(doSomethingConstant()) {
case OFFLINE_STATE:
dummy();
break;
}
}
echo(PHP_EOL);
$end = microtime(true);
echo($end - $start);
echo(PHP_EOL);

My php version:

PHP 7.2.8-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Jul 25 2018 10:52:19) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.8-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies

integer division in php

if it's division by 2, the fastest way to do it is bit shifting.

5>>1 = 2
6>>1 = 3

and so on and so forth.
What it does is just shift the bits to the right by 1 bit, thus dividing the number by 2 and losing the rest

1110 >> 1 =  111
1011 >> 1 = 101
1011 >> 2 = 10 //division by 4
1011 << 1 =10110


Related Topics



Leave a reply



Submit