Topic: P0638R0: std::crochemore_perrin_searcher.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 4 Jul 2017 07:09:18 +0300
Raw View
On 4 July 2017 at 06:51,  <zamazan4ik@gmail.com> wrote:
> Hello.
>
> I work on search algorithms in Boost.Algorithm. And i have some thoughts
> about your proposal:
> 1) Do you have comparison between naive search vs Crochemore-Perrin vs
> Boyer-Moore? I have benchmarked Crochemore-Perrin vs Boyer-Moore, and i can
> say that Crochemore-Perrin (as known as Two-way search algorithm (TW)) is
> always slower. And it's without comparison between Musser-Nishanov algorithm
> vs TW (Musser-Nishanov is faster than BM).
> 2) TW requires Random Access Iterators. BM too.
>
> So can you explain me please, why we should add this algorithm to standard
> library?

Crochemore-Perrin is a constant-space algorithm, whereas Boyer-Moore isn't. That
would seem nice-to-have for uses that do not wish to have the dynamic
allocation.
In other words, Boyer-Moore would win every benchmark you throw at these
algorithms, except the one where you can't run Boyer-Moore at all. :)

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUZU28k1KkSHq0-KrxR-_%3DcaSd06HVmDQ0pQkG45xNr%3DUg%40mail.gmail.com.

.


Author: zamazan4ik@gmail.com
Date: Mon, 3 Jul 2017 21:33:18 -0700 (PDT)
Raw View
------=_Part_2192_264106316.1499142798531
Content-Type: multipart/alternative;
 boundary="----=_Part_2193_1701673399.1499142798531"

------=_Part_2193_1701673399.1499142798531
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Yeah, i know that TW is constant-space algorithm. But is enough this=20
feature for including into Standard? IMHO, no (maybe i didn't know some=20
details).

About possibility for using as constexpr. There is proposal about=20
constexpr_allocator, which can make all STL containers constexpr by=20
default, so BM and Boyer-Moore-Horspool (BMH) will become also constexpr.

Maybe in a day i can show you some benchmarks between naive search and TW=
=20
algorithms (i think, TW wins. But how many percents TW will win? And also=
=20
TW has a lot of restrictions, which naive search has not).

I think, that current situation with search algorithms isn't so terrible -=
=20
BM and BMH are fast enough. Yep, there are faster algorithms, but BM and=20
BMH are widely-used.

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=D1=8E=D0=BB=D1=8F 2017=
 =D0=B3., 7:09:21 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=
=82=D0=B5=D0=BB=D1=8C Ville Voutilainen=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> On 4 July 2017 at 06:51,  <zamaz...@gmail.com <javascript:>> wrote:=20
> > Hello.=20
> >=20
> > I work on search algorithms in Boost.Algorithm. And i have some thought=
s=20
> > about your proposal:=20
> > 1) Do you have comparison between naive search vs Crochemore-Perrin vs=
=20
> > Boyer-Moore? I have benchmarked Crochemore-Perrin vs Boyer-Moore, and i=
=20
> can=20
> > say that Crochemore-Perrin (as known as Two-way search algorithm (TW))=
=20
> is=20
> > always slower. And it's without comparison between Musser-Nishanov=20
> algorithm=20
> > vs TW (Musser-Nishanov is faster than BM).=20
> > 2) TW requires Random Access Iterators. BM too.=20
> >=20
> > So can you explain me please, why we should add this algorithm to=20
> standard=20
> > library?=20
>
> Crochemore-Perrin is a constant-space algorithm, whereas Boyer-Moore=20
> isn't. That=20
> would seem nice-to-have for uses that do not wish to have the dynamic=20
> allocation.=20
> In other words, Boyer-Moore would win every benchmark you throw at these=
=20
> algorithms, except the one where you can't run Boyer-Moore at all. :)=20
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/9ff5860a-e5e2-4b06-9ad6-d4cec6a35547%40isocpp.or=
g.

------=_Part_2193_1701673399.1499142798531
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Yeah, i know that TW is constant-space algorithm. But is e=
nough this feature for including into Standard? IMHO, no (maybe i didn&#39;=
t know some details).<div><br></div><div>About possibility for using as con=
stexpr. There is proposal about constexpr_allocator, which can make all STL=
 containers constexpr by default, so BM and Boyer-Moore-Horspool (BMH) will=
 become also constexpr.</div><div><br></div><div>Maybe in a day i can show =
you some benchmarks between naive search and TW algorithms (i think, TW win=
s. But how many percents TW will win? And also TW has a lot of restrictions=
, which naive search has not).</div><div><br></div><div>I think, that curre=
nt situation with search algorithms isn&#39;t so terrible - BM and BMH are =
fast enough. Yep, there are faster algorithms, but BM and BMH are widely-us=
ed.<br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=D1=8E=D0=BB=
=D1=8F 2017 =D0=B3., 7:09:21 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=
=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Ville Voutilainen =D0=BD=D0=B0=D0=BF=D0=
=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 4 Jul=
y 2017 at 06:51, =C2=A0&lt;<a href=3D"javascript:" target=3D"_blank" gdf-ob=
fuscated-mailto=3D"0dj_RMzuAQAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascri=
pt:&#39;;return true;">zamaz...@gmail.com</a>&gt; wrote:
<br>&gt; Hello.
<br>&gt;
<br>&gt; I work on search algorithms in Boost.Algorithm. And i have some th=
oughts
<br>&gt; about your proposal:
<br>&gt; 1) Do you have comparison between naive search vs Crochemore-Perri=
n vs
<br>&gt; Boyer-Moore? I have benchmarked Crochemore-Perrin vs Boyer-Moore, =
and i can
<br>&gt; say that Crochemore-Perrin (as known as Two-way search algorithm (=
TW)) is
<br>&gt; always slower. And it&#39;s without comparison between Musser-Nish=
anov algorithm
<br>&gt; vs TW (Musser-Nishanov is faster than BM).
<br>&gt; 2) TW requires Random Access Iterators. BM too.
<br>&gt;
<br>&gt; So can you explain me please, why we should add this algorithm to =
standard
<br>&gt; library?
<br>
<br>Crochemore-Perrin is a constant-space algorithm, whereas Boyer-Moore is=
n&#39;t. That
<br>would seem nice-to-have for uses that do not wish to have the dynamic
<br>allocation.
<br>In other words, Boyer-Moore would win every benchmark you throw at thes=
e
<br>algorithms, except the one where you can&#39;t run Boyer-Moore at all. =
:)
<br></blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9ff5860a-e5e2-4b06-9ad6-d4cec6a35547%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9ff5860a-e5e2-4b06-9ad6-d4cec6a35547=
%40isocpp.org</a>.<br />

------=_Part_2193_1701673399.1499142798531--

------=_Part_2192_264106316.1499142798531--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 4 Jul 2017 07:46:11 +0300
Raw View
On 4 July 2017 at 07:33,  <zamazan4ik@gmail.com> wrote:
> Yeah, i know that TW is constant-space algorithm. But is enough this feature
> for including into Standard? IMHO, no (maybe i didn't know some details).

Seems handy to have when BM can't be used. But, here's a question: is
there some reason
why a string search can't use TW internally? It can't use BM due to
the preprocessing,
but why not TW? Why would it need to be a separate searcher?

> Maybe in a day i can show you some benchmarks between naive search and TW
> algorithms (i think, TW wins. But how many percents TW will win? And also TW
> has a lot of restrictions, which naive search has not).

Data is always good to have.

> I think, that current situation with search algorithms isn't so terrible -
> BM and BMH are fast enough. Yep, there are faster algorithms, but BM and BMH
> are widely-used.

Speed superior to BM/BMH is not the reason to add TW, semi-obviously.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUb4s-zi9Tm%3Dn_W2UFnSiyeis-i_EX%2B058W5VF-TBhnbeA%40mail.gmail.com.

.


Author: zamazan4ik@gmail.com
Date: Mon, 3 Jul 2017 21:52:46 -0700 (PDT)
Raw View
------=_Part_2156_1915859997.1499143966447
Content-Type: multipart/alternative;
 boundary="----=_Part_2157_648487848.1499143966448"

------=_Part_2157_648487848.1499143966448
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable


>
> Seems handy to have when BM can't be used. But, here's a question: is=20
> there some reason=20
> why a string search can't use TW internally? It can't use BM due to=20
> the preprocessing,=20
> but why not TW? Why would it need to be a separate searcher?=20


We don't talk about std::string only. std::search is general algorithm, so=
=20
it can used for no only std::string. In this case we must support not only=
=20
Random access iterators (BM and BMH), but also other iterators (now we do=
=20
it with naive search). TW requires Random Access iterators. Reason of=20
appearing searchers in Standard is give to programmer possibility to choose=
=20
search algorithm (by default we use naive search, because it works even on=
=20
Forward Iterators).

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=D1=8E=D0=BB=D1=8F 2017=
 =D0=B3., 7:46:14 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=
=82=D0=B5=D0=BB=D1=8C Ville Voutilainen=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> On 4 July 2017 at 07:33,  <zamaz...@gmail.com <javascript:>> wrote:=20
> > Yeah, i know that TW is constant-space algorithm. But is enough this=20
> feature=20
> > for including into Standard? IMHO, no (maybe i didn't know some=20
> details).=20
>
> Seems handy to have when BM can't be used. But, here's a question: is=20
> there some reason=20
> why a string search can't use TW internally? It can't use BM due to=20
> the preprocessing,=20
> but why not TW? Why would it need to be a separate searcher?=20
>
> > Maybe in a day i can show you some benchmarks between naive search and=
=20
> TW=20
> > algorithms (i think, TW wins. But how many percents TW will win? And=20
> also TW=20
> > has a lot of restrictions, which naive search has not).=20
>
> Data is always good to have.=20
>
> > I think, that current situation with search algorithms isn't so terribl=
e=20
> -=20
> > BM and BMH are fast enough. Yep, there are faster algorithms, but BM an=
d=20
> BMH=20
> > are widely-used.=20
>
> Speed superior to BM/BMH is not the reason to add TW, semi-obviously.=20
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/a1d31cd1-0492-4d9a-96b4-38abd313de2a%40isocpp.or=
g.

------=_Part_2157_648487848.1499143966448
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">=
Seems handy to have when BM can&#39;t be used. But, here&#39;s a question: =
is=C2=A0<br>there some reason=C2=A0<br>why a string search can&#39;t use TW=
 internally? It can&#39;t use BM due to=C2=A0<br>the preprocessing,=C2=A0<b=
r>but why not TW? Why would it need to be a separate searcher?=C2=A0</block=
quote><div><br></div><div>We don&#39;t talk about std::string only. std::se=
arch is general algorithm, so it can used for no only std::string. In this =
case we must support not only Random access iterators (BM and BMH), but als=
o other iterators (now we do it with naive search). TW requires Random Acce=
ss iterators. Reason of appearing searchers in Standard is give to programm=
er possibility to choose search algorithm (by default we use naive search, =
because it works even on Forward Iterators).</div><br>=D0=B2=D1=82=D0=BE=D1=
=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=D1=8E=D0=BB=D1=8F 2017 =D0=B3., 7:46:14 UTC=
+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=
 Ville Voutilainen =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
 #ccc solid;padding-left: 1ex;">On 4 July 2017 at 07:33, =C2=A0&lt;<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"lUsHn8_wAQAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">zamaz...@gma=
il.com</a>&gt; wrote:
<br>&gt; Yeah, i know that TW is constant-space algorithm. But is enough th=
is feature
<br>&gt; for including into Standard? IMHO, no (maybe i didn&#39;t know som=
e details).
<br>
<br>Seems handy to have when BM can&#39;t be used. But, here&#39;s a questi=
on: is
<br>there some reason
<br>why a string search can&#39;t use TW internally? It can&#39;t use BM du=
e to
<br>the preprocessing,
<br>but why not TW? Why would it need to be a separate searcher?
<br>
<br>&gt; Maybe in a day i can show you some benchmarks between naive search=
 and TW
<br>&gt; algorithms (i think, TW wins. But how many percents TW will win? A=
nd also TW
<br>&gt; has a lot of restrictions, which naive search has not).
<br>
<br>Data is always good to have.
<br>
<br>&gt; I think, that current situation with search algorithms isn&#39;t s=
o terrible -
<br>&gt; BM and BMH are fast enough. Yep, there are faster algorithms, but =
BM and BMH
<br>&gt; are widely-used.
<br>
<br>Speed superior to BM/BMH is not the reason to add TW, semi-obviously.
<br></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a1d31cd1-0492-4d9a-96b4-38abd313de2a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a1d31cd1-0492-4d9a-96b4-38abd313de2a=
%40isocpp.org</a>.<br />

------=_Part_2157_648487848.1499143966448--

------=_Part_2156_1915859997.1499143966447--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 4 Jul 2017 07:59:33 +0300
Raw View
On 4 July 2017 at 07:52,  <zamazan4ik@gmail.com> wrote:
>> Seems handy to have when BM can't be used. But, here's a question: is
>> there some reason
>> why a string search can't use TW internally? It can't use BM due to
>> the preprocessing,
>> but why not TW? Why would it need to be a separate searcher?
>
>
> We don't talk about std::string only. std::search is general algorithm, so
> it can used for no only std::string. In this case we must support not only
> Random access iterators (BM and BMH), but also other iterators (now we do it
> with naive search). TW requires Random Access iterators. Reason of appearing
> searchers in Standard is give to programmer possibility to choose search
> algorithm (by default we use naive search, because it works even on Forward
> Iterators).

So you're now answering your own question about why TW should be
standardized? :)

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUYWoBGuRFxj0Vk8LThuKXnC7JcyVWOFSzNWzMinB4r1uw%40mail.gmail.com.

.


Author: zamazan4ik@gmail.com
Date: Mon, 3 Jul 2017 22:02:17 -0700 (PDT)
Raw View
------=_Part_2149_1004914145.1499144537552
Content-Type: multipart/alternative;
 boundary="----=_Part_2150_705829681.1499144537553"

------=_Part_2150_705829681.1499144537553
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Before benchmarks between Naive search vs TW i can't agree with appearing=
=20
TW in Standard. Also i think that there are more efficient algorithm than=
=20
TW with similar requirements. We should research it before including.

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=D1=8E=D0=BB=D1=8F 2017=
 =D0=B3., 7:59:36 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=
=82=D0=B5=D0=BB=D1=8C Ville Voutilainen=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> On 4 July 2017 at 07:52,  <zamaz...@gmail.com <javascript:>> wrote:=20
> >> Seems handy to have when BM can't be used. But, here's a question: is=
=20
> >> there some reason=20
> >> why a string search can't use TW internally? It can't use BM due to=20
> >> the preprocessing,=20
> >> but why not TW? Why would it need to be a separate searcher?=20
> >=20
> >=20
> > We don't talk about std::string only. std::search is general algorithm,=
=20
> so=20
> > it can used for no only std::string. In this case we must support not=
=20
> only=20
> > Random access iterators (BM and BMH), but also other iterators (now we=
=20
> do it=20
> > with naive search). TW requires Random Access iterators. Reason of=20
> appearing=20
> > searchers in Standard is give to programmer possibility to choose searc=
h=20
> > algorithm (by default we use naive search, because it works even on=20
> Forward=20
> > Iterators).=20
>
> So you're now answering your own question about why TW should be=20
> standardized? :)=20
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/97631186-de21-4799-be8e-fdcbd0fcc62e%40isocpp.or=
g.

------=_Part_2150_705829681.1499144537553
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Before benchmarks between Naive search vs TW i can&#39;t a=
gree with appearing TW in Standard. Also i think that there are more effici=
ent algorithm than TW with similar requirements. We should research it befo=
re including.<br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=
=D1=8E=D0=BB=D1=8F 2017 =D0=B3., 7:59:36 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=
=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Ville Voutilainen =D0=BD=D0=
=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">On 4 July 2017 at 07:52, =C2=A0&lt;<a href=3D"javascript:" target=3D"=
_blank" gdf-obfuscated-mailto=3D"chFFQorxAQAJ" rel=3D"nofollow" onmousedown=
=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D=
&#39;javascript:&#39;;return true;">zamaz...@gmail.com</a>&gt; wrote:
<br>&gt;&gt; Seems handy to have when BM can&#39;t be used. But, here&#39;s=
 a question: is
<br>&gt;&gt; there some reason
<br>&gt;&gt; why a string search can&#39;t use TW internally? It can&#39;t =
use BM due to
<br>&gt;&gt; the preprocessing,
<br>&gt;&gt; but why not TW? Why would it need to be a separate searcher?
<br>&gt;
<br>&gt;
<br>&gt; We don&#39;t talk about std::string only. std::search is general a=
lgorithm, so
<br>&gt; it can used for no only std::string. In this case we must support =
not only
<br>&gt; Random access iterators (BM and BMH), but also other iterators (no=
w we do it
<br>&gt; with naive search). TW requires Random Access iterators. Reason of=
 appearing
<br>&gt; searchers in Standard is give to programmer possibility to choose =
search
<br>&gt; algorithm (by default we use naive search, because it works even o=
n Forward
<br>&gt; Iterators).
<br>
<br>So you&#39;re now answering your own question about why TW should be
<br>standardized? :)
<br></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/97631186-de21-4799-be8e-fdcbd0fcc62e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/97631186-de21-4799-be8e-fdcbd0fcc62e=
%40isocpp.org</a>.<br />

------=_Part_2150_705829681.1499144537553--

------=_Part_2149_1004914145.1499144537552--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 4 Jul 2017 08:05:52 +0300
Raw View
On 4 July 2017 at 08:02,  <zamazan4ik@gmail.com> wrote:
> Before benchmarks between Naive search vs TW i can't agree with appearing TW
> in Standard. Also i think that there are more efficient algorithm than TW
> with similar requirements. We should research it before including.

Ok, fully agreed on that. In general, having a constant-space searcher
(although a naive one is such
a searcher already) seems attractive, *if* it can provide an actual
benefit. Whether TW is that
solution is indeed something worth exploring.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUaSvb-2Dfbdg1nDmhMzjDe1a09eDztuFYJftV9GaADFJg%40mail.gmail.com.

.


Author: Ed Schouten <ed@nuxi.nl>
Date: Tue, 4 Jul 2017 09:20:07 +0200
Raw View
Hi there!

Thanks for taking the time to look into my proposal. Let me try to
respond to all of your messages in one go.

2017-07-04 6:09 GMT+02:00 Ville Voutilainen <ville.voutilainen@gmail.com>:
> Crochemore-Perrin is a constant-space algorithm, whereas Boyer-Moore isn't. That
> would seem nice-to-have for uses that do not wish to have the dynamic
> allocation.
> In other words, Boyer-Moore would win every benchmark you throw at these
> algorithms, except the one where you can't run Boyer-Moore at all. :)

Exactly. This is not a race to find the fastest search algorithm. It's
about providing a somewhat decent string searching algorithm that
works well on resource-constrained systems.

2017-07-04 6:46 GMT+02:00 Ville Voutilainen <ville.voutilainen@gmail.com>:
> On 4 July 2017 at 07:33,  <zamazan4ik@gmail.com> wrote:
> Seems handy to have when BM can't be used. But, here's a question: is
> there some reason why a string search can't use TW internally? It can't use BM due to
> the preprocessing, but why not TW? Why would it need to be a separate searcher?

So the problem with all of the existing searchers is that they are
defined to only do comparisons for equality. As Two-Way's
preprocessing algorithm depends on having a total order on the
alphabet, my proposal adds a searcher that may depend on std::less<>.

2017-07-04 7:05 GMT+02:00 Ville Voutilainen <ville.voutilainen@gmail.com>:
> On 4 July 2017 at 08:02,  <zamazan4ik@gmail.com> wrote:
>> Before benchmarks between Naive search vs TW i can't agree with appearing TW
>> in Standard. Also i think that there are more efficient algorithm than TW
>> with similar requirements. We should research it before including.
>
> Ok, fully agreed on that. In general, having a constant-space searcher
> (although a naive one is such
> a searcher already) seems attractive, *if* it can provide an actual
> benefit. Whether TW is that
> solution is indeed something worth exploring.

I have to confess, I am not an expert when it comes to benchmarking
string search algorithms. Question: are there some kind of
standardised test vectors that represent realistic workloads any of
you want me to use?

Anyway, as a quick experiment, I benchmarked the running time of
various string searching algorithms when given the following input:

Needle: 'A' * 999 + 'B'
Haystack: 'A' * 1000000

This means we'll be searching for a kilobyte-sized needle in a
megabyte-sized haystack, where the needle and haystack are structured
in such a way that a naive algorithm would perform very poorly. There
will obviously be no full match.

When running string searchers on FreeBSD 12.0 in VirtualBox on my 2,8
GHz Intel i7 Macbook Pro (late 2013 model), I observe the following
average running times for searching (i.e., not counting the
preprocessing phase), when built with Clang 4.0 at -O3:

Naive std::search(): 629.4 milliseconds (avg of 100 iterations)
libc++'s std::experimental::boyer_moore_searcher: 5.916 milliseconds
(avg of 10000 iterations)
libc++'s std::experimental::boyer_moore_horspool_searcher: 3.494
milliseconds (avg of 10000 iterations)
My implementation of std::crochemore_perrin_searcher: 1.079
milliseconds (avg of 10000 iterations)

--
Ed Schouten <ed@nuxi.nl>
Nuxi, 's-Hertogenbosch, the Netherlands
KvK-nr.: 62051717

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CABh_MKmea8OMhUhUptiFxJ53Wf%3Dn1jGSrrHcQEwgfNKiyZKWSQ%40mail.gmail.com.

.


Author: zamazan4ik@gmail.com
Date: Tue, 4 Jul 2017 03:45:24 -0700 (PDT)
Raw View
------=_Part_2299_378976920.1499165124275
Content-Type: multipart/alternative;
 boundary="----=_Part_2300_848935670.1499165124276"

------=_Part_2300_848935670.1499165124276
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Thank you for the brief explanation.

First: BM and BMH uses strong heuristics for searching. Not only simple=20
comparisons.

Second: Your benchmark is not from real world. It's very-very specific. I=
=20
have Good workable benchmark (provided by SMART). And later i will give you=
=20
my results.=20

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=D1=8E=D0=BB=D1=8F 2017=
 =D0=B3., 10:20:42 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Ed Schouten =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=
=D0=BB:
>
> Hi there!=20
>
> Thanks for taking the time to look into my proposal. Let me try to=20
> respond to all of your messages in one go.=20
>
> 2017-07-04 6:09 GMT+02:00 Ville Voutilainen <ville.vo...@gmail.com=20
> <javascript:>>:=20
> > Crochemore-Perrin is a constant-space algorithm, whereas Boyer-Moore=20
> isn't. That=20
> > would seem nice-to-have for uses that do not wish to have the dynamic=
=20
> > allocation.=20
> > In other words, Boyer-Moore would win every benchmark you throw at thes=
e=20
> > algorithms, except the one where you can't run Boyer-Moore at all. :)=
=20
>
> Exactly. This is not a race to find the fastest search algorithm. It's=20
> about providing a somewhat decent string searching algorithm that=20
> works well on resource-constrained systems.=20
>
> 2017-07-04 6:46 GMT+02:00 Ville Voutilainen <ville.vo...@gmail.com=20
> <javascript:>>:=20
> > On 4 July 2017 at 07:33,  <zamaz...@gmail.com <javascript:>> wrote:=20
> > Seems handy to have when BM can't be used. But, here's a question: is=
=20
> > there some reason why a string search can't use TW internally? It can't=
=20
> use BM due to=20
> > the preprocessing, but why not TW? Why would it need to be a separate=
=20
> searcher?=20
>
> So the problem with all of the existing searchers is that they are=20
> defined to only do comparisons for equality. As Two-Way's=20
> preprocessing algorithm depends on having a total order on the=20
> alphabet, my proposal adds a searcher that may depend on std::less<>.=20
>
> 2017-07-04 7:05 GMT+02:00 Ville Voutilainen <ville.vo...@gmail.com=20
> <javascript:>>:=20
> > On 4 July 2017 at 08:02,  <zamaz...@gmail.com <javascript:>> wrote:=20
> >> Before benchmarks between Naive search vs TW i can't agree with=20
> appearing TW=20
> >> in Standard. Also i think that there are more efficient algorithm than=
=20
> TW=20
> >> with similar requirements. We should research it before including.=20
> >=20
> > Ok, fully agreed on that. In general, having a constant-space searcher=
=20
> > (although a naive one is such=20
> > a searcher already) seems attractive, *if* it can provide an actual=20
> > benefit. Whether TW is that=20
> > solution is indeed something worth exploring.=20
>
> I have to confess, I am not an expert when it comes to benchmarking=20
> string search algorithms. Question: are there some kind of=20
> standardised test vectors that represent realistic workloads any of=20
> you want me to use?=20
>
> Anyway, as a quick experiment, I benchmarked the running time of=20
> various string searching algorithms when given the following input:=20
>
> Needle: 'A' * 999 + 'B'=20
> Haystack: 'A' * 1000000=20
>
> This means we'll be searching for a kilobyte-sized needle in a=20
> megabyte-sized haystack, where the needle and haystack are structured=20
> in such a way that a naive algorithm would perform very poorly. There=20
> will obviously be no full match.=20
>
> When running string searchers on FreeBSD 12.0 in VirtualBox on my 2,8=20
> GHz Intel i7 Macbook Pro (late 2013 model), I observe the following=20
> average running times for searching (i.e., not counting the=20
> preprocessing phase), when built with Clang 4.0 at -O3:=20
>
> Naive std::search(): 629.4 milliseconds (avg of 100 iterations)=20
> libc++'s std::experimental::boyer_moore_searcher: 5.916 milliseconds=20
> (avg of 10000 iterations)=20
> libc++'s std::experimental::boyer_moore_horspool_searcher: 3.494=20
> milliseconds (avg of 10000 iterations)=20
> My implementation of std::crochemore_perrin_searcher: 1.079=20
> milliseconds (avg of 10000 iterations)=20
>
> --=20
> Ed Schouten <e...@nuxi.nl <javascript:>>=20
> Nuxi, 's-Hertogenbosch, the Netherlands=20
> KvK-nr.: 62051717=20
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1ac1cfff-a2eb-432b-a0d5-42538a4c8bd5%40isocpp.or=
g.

------=_Part_2300_848935670.1499165124276
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Thank you for the brief explanation.<div><br><div>First: B=
M and BMH uses strong heuristics for searching. Not only simple comparisons=
..<br></div><div><br></div><div>Second: Your benchmark is not from real worl=
d. It&#39;s very-very specific. I have Good workable benchmark (provided by=
 SMART). And later i will give you my results.=C2=A0<br><br>=D0=B2=D1=82=D0=
=BE=D1=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=D1=8E=D0=BB=D1=8F 2017 =D0=B3., 10:20=
:42 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=
=BB=D1=8C Ed Schouten =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;">Hi there!
<br>
<br>Thanks for taking the time to look into my proposal. Let me try to
<br>respond to all of your messages in one go.
<br>
<br>2017-07-04 6:09 GMT+02:00 Ville Voutilainen &lt;<a href=3D"javascript:"=
 target=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" =
onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"t=
his.href=3D&#39;javascript:&#39;;return true;">ville.vo...@gmail.com</a>&gt=
;:
<br>&gt; Crochemore-Perrin is a constant-space algorithm, whereas Boyer-Moo=
re isn&#39;t. That
<br>&gt; would seem nice-to-have for uses that do not wish to have the dyna=
mic
<br>&gt; allocation.
<br>&gt; In other words, Boyer-Moore would win every benchmark you throw at=
 these
<br>&gt; algorithms, except the one where you can&#39;t run Boyer-Moore at =
all. :)
<br>
<br>Exactly. This is not a race to find the fastest search algorithm. It&#3=
9;s
<br>about providing a somewhat decent string searching algorithm that
<br>works well on resource-constrained systems.
<br>
<br>2017-07-04 6:46 GMT+02:00 Ville Voutilainen &lt;<a href=3D"javascript:"=
 target=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" =
onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"t=
his.href=3D&#39;javascript:&#39;;return true;">ville.vo...@gmail.com</a>&gt=
;:
<br>&gt; On 4 July 2017 at 07:33, =C2=A0&lt;<a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">zamaz...@gmail.com</a>&gt; wrote:
<br>&gt; Seems handy to have when BM can&#39;t be used. But, here&#39;s a q=
uestion: is
<br>&gt; there some reason why a string search can&#39;t use TW internally?=
 It can&#39;t use BM due to
<br>&gt; the preprocessing, but why not TW? Why would it need to be a separ=
ate searcher?
<br>
<br>So the problem with all of the existing searchers is that they are
<br>defined to only do comparisons for equality. As Two-Way&#39;s
<br>preprocessing algorithm depends on having a total order on the
<br>alphabet, my proposal adds a searcher that may depend on std::less&lt;&=
gt;.
<br>
<br>2017-07-04 7:05 GMT+02:00 Ville Voutilainen &lt;<a href=3D"javascript:"=
 target=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" =
onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"t=
his.href=3D&#39;javascript:&#39;;return true;">ville.vo...@gmail.com</a>&gt=
;:
<br>&gt; On 4 July 2017 at 08:02, =C2=A0&lt;<a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">zamaz...@gmail.com</a>&gt; wrote:
<br>&gt;&gt; Before benchmarks between Naive search vs TW i can&#39;t agree=
 with appearing TW
<br>&gt;&gt; in Standard. Also i think that there are more efficient algori=
thm than TW
<br>&gt;&gt; with similar requirements. We should research it before includ=
ing.
<br>&gt;
<br>&gt; Ok, fully agreed on that. In general, having a constant-space sear=
cher
<br>&gt; (although a naive one is such
<br>&gt; a searcher already) seems attractive, *if* it can provide an actua=
l
<br>&gt; benefit. Whether TW is that
<br>&gt; solution is indeed something worth exploring.
<br>
<br>I have to confess, I am not an expert when it comes to benchmarking
<br>string search algorithms. Question: are there some kind of
<br>standardised test vectors that represent realistic workloads any of
<br>you want me to use?
<br>
<br>Anyway, as a quick experiment, I benchmarked the running time of
<br>various string searching algorithms when given the following input:
<br>
<br>Needle: &#39;A&#39; * 999 + &#39;B&#39;
<br>Haystack: &#39;A&#39; * 1000000
<br>
<br>This means we&#39;ll be searching for a kilobyte-sized needle in a
<br>megabyte-sized haystack, where the needle and haystack are structured
<br>in such a way that a naive algorithm would perform very poorly. There
<br>will obviously be no full match.
<br>
<br>When running string searchers on FreeBSD 12.0 in VirtualBox on my 2,8
<br>GHz Intel i7 Macbook Pro (late 2013 model), I observe the following
<br>average running times for searching (i.e., not counting the
<br>preprocessing phase), when built with Clang 4.0 at -O3:
<br>
<br>Naive std::search(): 629.4 milliseconds (avg of 100 iterations)
<br>libc++&#39;s std::experimental::boyer_<wbr>moore_searcher: 5.916 millis=
econds
<br>(avg of 10000 iterations)
<br>libc++&#39;s std::experimental::boyer_<wbr>moore_horspool_searcher: 3.4=
94
<br>milliseconds (avg of 10000 iterations)
<br>My implementation of std::crochemore_perrin_<wbr>searcher: 1.079
<br>milliseconds (avg of 10000 iterations)
<br>
<br>--=20
<br>Ed Schouten &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscate=
d-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;=
javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;=
;return true;">e...@nuxi.nl</a>&gt;
<br>Nuxi, &#39;s-Hertogenbosch, the Netherlands
<br>KvK-nr.: 62051717
<br></blockquote></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1ac1cfff-a2eb-432b-a0d5-42538a4c8bd5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1ac1cfff-a2eb-432b-a0d5-42538a4c8bd5=
%40isocpp.org</a>.<br />

------=_Part_2300_848935670.1499165124276--

------=_Part_2299_378976920.1499165124275--

.


Author: Alexander Zaitsev <zamazan4ik@gmail.com>
Date: Tue, 4 Jul 2017 04:38:18 -0700 (PDT)
Raw View
------=_Part_2293_1235816165.1499168298513
Content-Type: multipart/alternative;
 boundary="----=_Part_2294_778750739.1499168298513"

------=_Part_2294_778750739.1499168298513
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Ok, i have benchmarked it just know. I have used SMART tool (tool was=20
written by scientists. SMART is project about researching search=20
algorithms).

Results are attached as 'results.zip' archive.

My system:
i7-3630QM, 12 Gib RAM, SSD, Kubuntu 17.04. CPU resources are free as much=
=20
as possible during tests.
Test program you can find here: https://github.com/smart-tool (you must=20
patch smart-gui for full compatibility with Qt5. I did it locally, sorry)

Short explanation:
BF is Brute-Force, naive algorithm
BM is Boyer-Moore
TW is Two-Way or Crochemore-Perrin.

My summary:
Results is unfortunately bad and i can't agree with accepting it into=20
Standard.=20

My suggestion: I am working on search algorithms in Boost.Algorithm.=20
Boost.Algorithm is very good place for testing new search algorithms. At=20
first i suggest you write proposal to Bost.Algorithm, i will be happy to=20
help you with it. And after our testing if your algorithm is really good,=
=20
we will add it to Boost.Algorithm, release it. And after 2-3 releases we=20
can write really full proposal (Sorry, your proposal is too short, without=
=20
benchmarks, etc. ) and send it to Comitee.=20

There are a lot of algorithms for searching, and Two-Way isn't one of the=
=20
best (even in this specific situation).

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=D1=8E=D0=BB=D1=8F 2017=
 =D0=B3., 10:20:42 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Ed Schouten =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=
=D0=BB:
>
> Hi there!=20
>
> Thanks for taking the time to look into my proposal. Let me try to=20
> respond to all of your messages in one go.=20
>
> 2017-07-04 6:09 GMT+02:00 Ville Voutilainen <ville.vo...@gmail.com=20
> <javascript:>>:=20
> > Crochemore-Perrin is a constant-space algorithm, whereas Boyer-Moore=20
> isn't. That=20
> > would seem nice-to-have for uses that do not wish to have the dynamic=
=20
> > allocation.=20
> > In other words, Boyer-Moore would win every benchmark you throw at thes=
e=20
> > algorithms, except the one where you can't run Boyer-Moore at all. :)=
=20
>
> Exactly. This is not a race to find the fastest search algorithm. It's=20
> about providing a somewhat decent string searching algorithm that=20
> works well on resource-constrained systems.=20
>
> 2017-07-04 6:46 GMT+02:00 Ville Voutilainen <ville.vo...@gmail.com=20
> <javascript:>>:=20
> > On 4 July 2017 at 07:33,  <zamaz...@gmail.com <javascript:>> wrote:=20
> > Seems handy to have when BM can't be used. But, here's a question: is=
=20
> > there some reason why a string search can't use TW internally? It can't=
=20
> use BM due to=20
> > the preprocessing, but why not TW? Why would it need to be a separate=
=20
> searcher?=20
>
> So the problem with all of the existing searchers is that they are=20
> defined to only do comparisons for equality. As Two-Way's=20
> preprocessing algorithm depends on having a total order on the=20
> alphabet, my proposal adds a searcher that may depend on std::less<>.=20
>
> 2017-07-04 7:05 GMT+02:00 Ville Voutilainen <ville.vo...@gmail.com=20
> <javascript:>>:=20
> > On 4 July 2017 at 08:02,  <zamaz...@gmail.com <javascript:>> wrote:=20
> >> Before benchmarks between Naive search vs TW i can't agree with=20
> appearing TW=20
> >> in Standard. Also i think that there are more efficient algorithm than=
=20
> TW=20
> >> with similar requirements. We should research it before including.=20
> >=20
> > Ok, fully agreed on that. In general, having a constant-space searcher=
=20
> > (although a naive one is such=20
> > a searcher already) seems attractive, *if* it can provide an actual=20
> > benefit. Whether TW is that=20
> > solution is indeed something worth exploring.=20
>
> I have to confess, I am not an expert when it comes to benchmarking=20
> string search algorithms. Question: are there some kind of=20
> standardised test vectors that represent realistic workloads any of=20
> you want me to use?=20
>
> Anyway, as a quick experiment, I benchmarked the running time of=20
> various string searching algorithms when given the following input:=20
>
> Needle: 'A' * 999 + 'B'=20
> Haystack: 'A' * 1000000=20
>
> This means we'll be searching for a kilobyte-sized needle in a=20
> megabyte-sized haystack, where the needle and haystack are structured=20
> in such a way that a naive algorithm would perform very poorly. There=20
> will obviously be no full match.=20
>
> When running string searchers on FreeBSD 12.0 in VirtualBox on my 2,8=20
> GHz Intel i7 Macbook Pro (late 2013 model), I observe the following=20
> average running times for searching (i.e., not counting the=20
> preprocessing phase), when built with Clang 4.0 at -O3:=20
>
> Naive std::search(): 629.4 milliseconds (avg of 100 iterations)=20
> libc++'s std::experimental::boyer_moore_searcher: 5.916 milliseconds=20
> (avg of 10000 iterations)=20
> libc++'s std::experimental::boyer_moore_horspool_searcher: 3.494=20
> milliseconds (avg of 10000 iterations)=20
> My implementation of std::crochemore_perrin_searcher: 1.079=20
> milliseconds (avg of 10000 iterations)=20
>
> --=20
> Ed Schouten <e...@nuxi.nl <javascript:>>=20
> Nuxi, 's-Hertogenbosch, the Netherlands=20
> KvK-nr.: 62051717=20
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/d4a1b508-81dc-4406-ac7f-0e615b6c10c8%40isocpp.or=
g.

------=_Part_2294_778750739.1499168298513
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Ok, i have benchmarked it just know. I have used SMART too=
l (tool was written by scientists. SMART is project about researching searc=
h algorithms).<div><br></div><div>Results are attached as &#39;results.zip&=
#39; archive.</div><div><br></div><div>My system:</div><div>i7-3630QM, 12 G=
ib RAM, SSD, Kubuntu 17.04. CPU resources are free as much as possible duri=
ng tests.</div><div>Test program you can find here:=C2=A0https://github.com=
/smart-tool (you must patch smart-gui for full compatibility with Qt5. I di=
d it locally, sorry)</div><div><br></div><div>Short explanation:</div><div>=
BF is Brute-Force, naive algorithm</div><div>BM is Boyer-Moore</div><div>TW=
 is Two-Way or Crochemore-Perrin.</div><div><br></div><div>My summary:</div=
><div>Results is unfortunately bad and i can&#39;t agree with accepting it =
into Standard.=C2=A0</div><div><br></div><div>My suggestion: I am working o=
n search algorithms in Boost.Algorithm. Boost.Algorithm is very good place =
for testing new search algorithms. At first i suggest you write proposal to=
 Bost.Algorithm, i will be happy to help you with it. And after our testing=
 if your algorithm is really good, we will add it to Boost.Algorithm, relea=
se it. And after 2-3 releases we can write really full proposal (Sorry, you=
r proposal is too short, without benchmarks, etc. ) and send it to Comitee.=
=C2=A0</div><div><br></div><div>There are a lot of algorithms for searching=
, and Two-Way isn&#39;t one of the best (even in this specific situation).<=
br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 4 =D0=B8=D1=8E=D0=BB=D1=
=8F 2017 =D0=B3., 10:20:42 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=
=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Ed Schouten =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=
=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi there!
<br>
<br>Thanks for taking the time to look into my proposal. Let me try to
<br>respond to all of your messages in one go.
<br>
<br>2017-07-04 6:09 GMT+02:00 Ville Voutilainen &lt;<a href=3D"javascript:"=
 target=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" =
onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"t=
his.href=3D&#39;javascript:&#39;;return true;">ville.vo...@gmail.com</a>&gt=
;:
<br>&gt; Crochemore-Perrin is a constant-space algorithm, whereas Boyer-Moo=
re isn&#39;t. That
<br>&gt; would seem nice-to-have for uses that do not wish to have the dyna=
mic
<br>&gt; allocation.
<br>&gt; In other words, Boyer-Moore would win every benchmark you throw at=
 these
<br>&gt; algorithms, except the one where you can&#39;t run Boyer-Moore at =
all. :)
<br>
<br>Exactly. This is not a race to find the fastest search algorithm. It&#3=
9;s
<br>about providing a somewhat decent string searching algorithm that
<br>works well on resource-constrained systems.
<br>
<br>2017-07-04 6:46 GMT+02:00 Ville Voutilainen &lt;<a href=3D"javascript:"=
 target=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" =
onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"t=
his.href=3D&#39;javascript:&#39;;return true;">ville.vo...@gmail.com</a>&gt=
;:
<br>&gt; On 4 July 2017 at 07:33, =C2=A0&lt;<a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">zamaz...@gmail.com</a>&gt; wrote:
<br>&gt; Seems handy to have when BM can&#39;t be used. But, here&#39;s a q=
uestion: is
<br>&gt; there some reason why a string search can&#39;t use TW internally?=
 It can&#39;t use BM due to
<br>&gt; the preprocessing, but why not TW? Why would it need to be a separ=
ate searcher?
<br>
<br>So the problem with all of the existing searchers is that they are
<br>defined to only do comparisons for equality. As Two-Way&#39;s
<br>preprocessing algorithm depends on having a total order on the
<br>alphabet, my proposal adds a searcher that may depend on std::less&lt;&=
gt;.
<br>
<br>2017-07-04 7:05 GMT+02:00 Ville Voutilainen &lt;<a href=3D"javascript:"=
 target=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" =
onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"t=
his.href=3D&#39;javascript:&#39;;return true;">ville.vo...@gmail.com</a>&gt=
;:
<br>&gt; On 4 July 2017 at 08:02, =C2=A0&lt;<a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">zamaz...@gmail.com</a>&gt; wrote:
<br>&gt;&gt; Before benchmarks between Naive search vs TW i can&#39;t agree=
 with appearing TW
<br>&gt;&gt; in Standard. Also i think that there are more efficient algori=
thm than TW
<br>&gt;&gt; with similar requirements. We should research it before includ=
ing.
<br>&gt;
<br>&gt; Ok, fully agreed on that. In general, having a constant-space sear=
cher
<br>&gt; (although a naive one is such
<br>&gt; a searcher already) seems attractive, *if* it can provide an actua=
l
<br>&gt; benefit. Whether TW is that
<br>&gt; solution is indeed something worth exploring.
<br>
<br>I have to confess, I am not an expert when it comes to benchmarking
<br>string search algorithms. Question: are there some kind of
<br>standardised test vectors that represent realistic workloads any of
<br>you want me to use?
<br>
<br>Anyway, as a quick experiment, I benchmarked the running time of
<br>various string searching algorithms when given the following input:
<br>
<br>Needle: &#39;A&#39; * 999 + &#39;B&#39;
<br>Haystack: &#39;A&#39; * 1000000
<br>
<br>This means we&#39;ll be searching for a kilobyte-sized needle in a
<br>megabyte-sized haystack, where the needle and haystack are structured
<br>in such a way that a naive algorithm would perform very poorly. There
<br>will obviously be no full match.
<br>
<br>When running string searchers on FreeBSD 12.0 in VirtualBox on my 2,8
<br>GHz Intel i7 Macbook Pro (late 2013 model), I observe the following
<br>average running times for searching (i.e., not counting the
<br>preprocessing phase), when built with Clang 4.0 at -O3:
<br>
<br>Naive std::search(): 629.4 milliseconds (avg of 100 iterations)
<br>libc++&#39;s std::experimental::boyer_<wbr>moore_searcher: 5.916 millis=
econds
<br>(avg of 10000 iterations)
<br>libc++&#39;s std::experimental::boyer_<wbr>moore_horspool_searcher: 3.4=
94
<br>milliseconds (avg of 10000 iterations)
<br>My implementation of std::crochemore_perrin_<wbr>searcher: 1.079
<br>milliseconds (avg of 10000 iterations)
<br>
<br>--=20
<br>Ed Schouten &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscate=
d-mailto=3D"DYqUZD35AQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;=
javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;=
;return true;">e...@nuxi.nl</a>&gt;
<br>Nuxi, &#39;s-Hertogenbosch, the Netherlands
<br>KvK-nr.: 62051717
<br></blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d4a1b508-81dc-4406-ac7f-0e615b6c10c8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d4a1b508-81dc-4406-ac7f-0e615b6c10c8=
%40isocpp.org</a>.<br />

------=_Part_2294_778750739.1499168298513--

------=_Part_2293_1235816165.1499168298513
Content-Type: application/zip; name=results.zip
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=results.zip
X-Attachment-Id: c77f3e3c-5bf9-4888-bb44-abc2da2716a4
Content-ID: <c77f3e3c-5bf9-4888-bb44-abc2da2716a4>

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

------=_Part_2293_1235816165.1499168298513--

.


Author: Ed Schouten <ed@nuxi.nl>
Date: Tue, 4 Jul 2017 17:55:26 +0200
Raw View
Alexander,

2017-07-04 13:38 GMT+02:00 Alexander Zaitsev <zamazan4ik@gmail.com>:
> Results is unfortunately bad and i can't agree with accepting it into
> Standard.

I agree with you that the results of the Two-Way algorithm are
obviously not as good as Boyer-Moore, but we are clearly in
disagreement about what to conclude from your measurements.

Looking at the results of the benchmarks you provided, it seems that
the Two-Way algorithm performs rather similar to the na=C3=AFve algorithm.
It looks like it doesn't really matter which one you pick for these
specific benchmarks. Sometimes it's faster, sometimes it's slower.
That said, none of the benchmark results you presented correspond with
degenerate cases. It's either the English/Italian dictionary or
randomly generated strings, right?

Because of this, I think the Two-Way algorithm truly shows its
strength: you've shown that it works equally well for common use,
except that we know it can't ever regress to a quadratic running time.
This is exactly what my proposal tries to cover. A string-searching
algorithm that:

- is in-place,
- runs in linear time,
- doesn't perform worse,
- is relatively compact, at least when compared to the
Boyer-Moore(-Horspool) searchers.

> There are a lot of algorithms for searching, and Two-Way isn't one of the
> best (even in this specific situation).

Sure. Lots of other algorithms and even variations on Two-Way exist.
Libraries like glibc, musl, etc. also combine Two-Way with a skip
table, but technically speaking, that makes the algorithm no longer
in-place. The size of the skip table depends on the size of the
alphabet.

What kind of in-place, worst-case linear time algorithm would you
propose instead?

--=20
Ed Schouten <ed@nuxi.nl>
Nuxi, 's-Hertogenbosch, the Netherlands
KvK-nr.: 62051717

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CABh_MK%3DM78cn%3DxszadqCTDS48Cuaw-6ho891YRDqn4Q=
XDtP3%3DQ%40mail.gmail.com.

.