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_uchar
s 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
Session_Start() Creates New Session Every Refresh
Blank Spaces in Column Names with MySQL
Codeigniter Back Button After Logout
How to Discover Rss Feeds for a Given Url
Update Xampp from Maria Db 10.1 to 10.2
Quickest Way to Read First Line from File
Multiple Auto Increment in MySQL
How to Make MySQLi Connect Function
Yii2 Global Filter/Behavior to Force User to Authenticate First
PHP Method="Post" Stopped Working After I Added This .Htaccess... Why
Check If Current User Is Administrator in Wordpress
PHP Preg_Match - Only Allow Alphanumeric Strings and - _ Characters
Displaying Multiple Lines of a File, Never Repeating
Get Return Value from SQL Stored Procedure Using PHP
Block Specific Ip Block from My Website in PHP
Friend of a Friend in PHP/Mysql
Cannot Use Concatenation When Declaring Default Class Properties in PHP