Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.php > #12837 > unrolled thread
| Started by | Jason C <jwcarlton@gmail.com> |
|---|---|
| First post | 2014-02-16 01:49 -0800 |
| Last post | 2014-02-16 20:49 +0000 |
| Articles | 5 on this page of 25 — 9 participants |
Back to article view | Back to comp.lang.php
strpos() before str_replace()? Or, maybe strtr()? Jason C <jwcarlton@gmail.com> - 2014-02-16 01:49 -0800
Re: strpos() before str_replace()? Or, maybe strtr()? bill <william@TechServSys.com> - 2014-02-16 07:10 -0500
Re: strpos() before str_replace()? Or, maybe strtr()? "J.O. Aho" <user@example.net> - 2014-02-16 14:55 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-02-16 15:10 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-02-16 20:24 +0000
Re: strpos() before str_replace()? Or, maybe strtr()? "J.O. Aho" <user@example.net> - 2014-02-16 21:41 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-02-16 20:51 +0000
Re: strpos() before str_replace()? Or, maybe strtr()? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-02-16 22:16 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-02-16 23:13 +0000
Re: strpos() before str_replace()? Or, maybe strtr()? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-02-18 01:33 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? "J.O. Aho" <user@example.net> - 2014-02-17 06:35 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-02-17 14:14 +0000
Re: strpos() before str_replace()? Or, maybe strtr()? "J.O. Aho" <user@example.net> - 2014-02-17 18:55 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Christoph Michael Becker <cmbecker69@arcor.de> - 2014-02-17 19:30 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Jerry Stuckle <jstucklex@attglobal.net> - 2014-02-16 09:15 -0500
Re: strpos() before str_replace()? Or, maybe strtr()? Christoph Michael Becker <cmbecker69@arcor.de> - 2014-02-16 15:45 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-02-16 17:23 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Christoph Michael Becker <cmbecker69@arcor.de> - 2014-02-16 17:41 +0100
Re: strpos() before str_replace()? Or, maybe strtr()? Norman Peelman <npeelman@cfl.rr.com> - 2014-02-16 10:08 -0500
Re: strpos() before str_replace()? Or, maybe strtr()? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-02-16 19:21 +0000
Re: strpos() before str_replace()? Or, maybe strtr()? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-02-16 20:53 +0000
Re: strpos() before str_replace()? Or, maybe strtr()? Denis McMahon <denismfmcmahon@gmail.com> - 2014-02-17 01:44 +0000
Re: strpos() before str_replace()? Or, maybe strtr()? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-02-17 02:19 +0000
Re: strpos() before str_replace()? Or, maybe strtr()? Norman Peelman <npeelman@cfl.rr.com> - 2014-02-16 18:17 -0500
Re: strpos() before str_replace()? Or, maybe strtr()? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-02-16 20:49 +0000
Page 2 of 2 — ← Prev page 1 [2]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2014-02-16 20:53 +0000 |
| Message-ID | <0.157e1f73edc557692509.20140216205352GMT.87mwhq6aov.fsf@bsb.me.uk> |
| In reply to | #12846 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Norman Peelman <npeelman@cfl.rr.com> writes:
>
>> On 02/16/2014 04:49 AM, Jason C wrote:
> <snip>
>>> foreach ($userArr as $key => $val) {
>>> if (strpos($firstname, $key) !== false)
>>> $firstname = str_replace($key, "****", $firstname);
>>>
>>> if (strpos($lastname, $key) !== false)
>>> $lastname = str_replace($key, "****", $lastname);
>>> }
>>
>>
>> It's slower because you are actually performing the same function
>> twice on each iteration.
>
> Did you try it? In my tests it's faster (37ms vs 66ms). This may be
> because of the assignment always being done.
I'm pretty sure that it is simply the overhead of str_replace compared
to that of strpos, and not to do with the assignment.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2014-02-17 01:44 +0000 |
| Message-ID | <ldrphe$4l4$2@dont-email.me> |
| In reply to | #12851 |
On Sun, 16 Feb 2014 20:53:52 +0000, Ben Bacarisse wrote:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>
>> Norman Peelman <npeelman@cfl.rr.com> writes:
>>
>>> On 02/16/2014 04:49 AM, Jason C wrote:
>> <snip>
>>>> foreach ($userArr as $key => $val) {
>>>> if (strpos($firstname, $key) !== false)
>>>> $firstname = str_replace($key, "****", $firstname);
>>>>
>>>> if (strpos($lastname, $key) !== false)
>>>> $lastname = str_replace($key, "****", $lastname);
>>>> }
>>>
>>>
>>> It's slower because you are actually performing the same function
>>> twice on each iteration.
>>
>> Did you try it? In my tests it's faster (37ms vs 66ms). This may be
>> because of the assignment always being done.
>
> I'm pretty sure that it is simply the overhead of str_replace compared
> to that of strpos, and not to do with the assignment.
>
> <snip>
Not sure whether something like this could be faster or not:
foreach ( $userArr as $key => $val ) {
if ( ( $f = strpos( $firstname, $key ) ) !== false )
$firstname = substr( $firstname, 0, $f ) . "****" .
substr( $firstname, $f + strlen( $key ) );
if ( ( $l = strpos( $lastname, $key ) ) !== false )
$lastname = substr( $lastname, 0, $l ) . "****" .
substr( $lastname, $l + strlen( $key ) );
}
As I don't have representative data to test against.
You could use a function:
function replace_stars( $needle, $pos, $haystack ) {
return substr( $haystack, 0, $pos ) . "****" .
substr( $haystack, $pos + strlen( $needle ) );
}
foreach ( $userArr as $key => $val ) {
if ( ( $f = strpos( $firstname, $key ) ) !== false )
$firstname = replace_stars( $key, $f, $firstname );
if ( ( $l = strpos( $lastname, $key ) ) !== false )
$lastname = replace_stars( $key, $f, $lastname );
}
but that would be an extra function call, so I inlined the code instead.
p.s. Yes richard, I used an "=" inside an if test, but the difference is
that I know what I'm doing when I do that, and you don't!
--
Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2014-02-17 02:19 +0000 |
| Message-ID | <0.36390c759f730e42bbfe.20140217021938GMT.8761oe5vlx.fsf@bsb.me.uk> |
| In reply to | #12855 |
Denis McMahon <denismfmcmahon@gmail.com> writes:
<snip>
> Not sure whether something like this could be faster or not:
>
> foreach ( $userArr as $key => $val ) {
>
> if ( ( $f = strpos( $firstname, $key ) ) !== false )
> $firstname = substr( $firstname, 0, $f ) . "****" .
> substr( $firstname, $f + strlen( $key ) );
>
> if ( ( $l = strpos( $lastname, $key ) ) !== false )
> $lastname = substr( $lastname, 0, $l ) . "****" .
> substr( $lastname, $l + strlen( $key ) );
>
> }
>
> As I don't have representative data to test against.
Given the structure of the data (lots of tests, with rate matches) I'd
expect this to be much like the strpos + str_replace solution, since the
speed of determining that there is no match dominates. The assignment
to $l might have a small effect, and that seems to be the case. The
timings show it's a few percent slower than the plain strpos+str_replace
solution.
The situation is an odd one. Matches are very rare, and this makes it
worthwhile avoiding as much work as possible when there is no match.
The positions $f and $l are only needed when there is a match, so,
oddly, it makes sense to re-calculate them rather than to assign them
every time. I.e. this unlikely pattern:
if (strpos( $firstname, $key) !== false ) {
$f = strpos($firstname, $key);
$firstname = substr($firstname, 0, $f) . "****" .
substr($firstname, $f + strlen($key));
}
is faster than the above (but by a small, if consistent, amount).
Avoiding 99,999 assignments at the cost of maybe one strpos call is a
win (though I am sure you can construct data sets that reduce or
eliminate this advantage). When there is no match at all (which the OP
describes as a likely event), avoiding 100,000 assignments at the cost
of nothing, can't be anything but a win!
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Norman Peelman <npeelman@cfl.rr.com> |
|---|---|
| Date | 2014-02-16 18:17 -0500 |
| Message-ID | <ldrgu9$441$1@dont-email.me> |
| In reply to | #12846 |
On 02/16/2014 02:21 PM, Ben Bacarisse wrote:
> Norman Peelman <npeelman@cfl.rr.com> writes:
>
>> On 02/16/2014 04:49 AM, Jason C wrote:
> <snip>
>>> foreach ($userArr as $key => $val) {
>>> if (strpos($firstname, $key) !== false)
>>> $firstname = str_replace($key, "****", $firstname);
>>>
>>> if (strpos($lastname, $key) !== false)
>>> $lastname = str_replace($key, "****", $lastname);
>>> }
>>
>>
>> It's slower because you are actually performing the same function
>> twice on each iteration.
>
> Did you try it? In my tests it's faster (37ms vs 66ms). This may be
> because of the assignment always being done.
>
> I am not saying you could not have got different numbers, just that the
> only way to be sure is to test with the real data in the real
> environment.
>
Thanks for pointing that out. I didn't think of it that way.
--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2014-02-16 20:49 +0000 |
| Message-ID | <0.5845e901a879f6166491.20140216204914GMT.87y51a6awl.fsf@bsb.me.uk> |
| In reply to | #12837 |
Jason C <jwcarlton@gmail.com> writes:
> I know that I'm talking about microseconds here, so this is really
> just for the sake of furthering my own education.
>
> I'm looping through roughly 100,000 values:
>
> $userArr = array(
> "something" => "anything",
> ...
> );
>
> foreach ($userArr as $key => $val) {
> $firstname = str_replace($key, "****", $firstname);
> $lastname = str_replace($key, "****", $lastname);
> }
>
> Both $firstname AND $lastname could contain any of the keys, but could
> only potentially contain one key each. It's likely, though, that
> neither will contain any of the keys.
>
> Would it be faster to use strpos() before each str_replace(), like so?:
>
> foreach ($userArr as $key => $val) {
> if (strpos($firstname, $key) !== false)
> $firstname = str_replace($key, "****", $firstname);
>
> if (strpos($lastname, $key) !== false)
> $lastname = str_replace($key, "****", $lastname);
> }
In a simple test, it seems to be a faster -- significantly faster in
relative terms but not much in absolute time. The exact numbers depend
on the length of the strings, whether one of the 100,000 strings really
is present or not, the exact keys used and so on, but in all cases that
I tested, checking strpos first pays off. A typical run: 64ms vs
33ms.
I first thought this might be because of the assignment, but it turns
out not to be. I think the cause is that str_replace has a high
overhead -- it does more before it ever gets going. If you can save
this overhead on 99,999 occasions, you save overall despite scanning the
string twice that one time.
Of course, as with all measurements like this, I may not have properly
duplicated your situation, and the result will depend on the machine,
the PHP version, and more besides, so take it with a pinch of salt.
(And note that if the key is numeric, strpos does not do what you
think!)
<snip>
> Or, would strtr() be faster? I've never actually used this function in
> practice; I think it's a slow function, but have never tested it, and
> don't remember where I read that:
>
> $firstname = strtr($firstname, $userArr);
> $lastname = strtr($lastname, $userArr);
In my test, about 89ms -- slower than either of the two above but if
it gives the right result (there is a slight difference in meaning as
pointed out elsethread) I'd probably use it for the clarity it brings.
> Any other suggestions on what might be the fastest option?
If you already have (or could have) the keys and the values in separate
arrays, using the array version of str_replace tested reasonably well
(66ms). However, as you start off by saying, it's all very marginal. I
would not normally measure this sort of thing; I'd just write the
simplest code and forget about it.
--
Ben.
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.php
csiph-web