From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Tianxiang Xiong Newsgroups: gmane.emacs.devel Subject: Re: Performance issue w/ `cl-loop`s `collect...into` Date: Sun, 8 Apr 2018 19:16:08 -0700 Message-ID: References: <41631665-6cd6-7096-8866-5ab9559a14ef@gmail.com> <1d5b85f5-62cd-f2f3-0b71-9e2a2cf2ef9e@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="94eb2c1956ea3743bc056960fd18" X-Trace: blaine.gmane.org 1523240096 21951 195.159.176.226 (9 Apr 2018 02:14:56 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 9 Apr 2018 02:14:56 +0000 (UTC) Cc: Emacs developers To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Apr 09 04:14:51 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1f5MKZ-0005bs-E4 for ged-emacs-devel@m.gmane.org; Mon, 09 Apr 2018 04:14:51 +0200 Original-Received: from localhost ([::1]:48918 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f5MMf-0004Wu-1s for ged-emacs-devel@m.gmane.org; Sun, 08 Apr 2018 22:17:01 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:51075) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f5MLs-0004WV-F6 for emacs-devel@gnu.org; Sun, 08 Apr 2018 22:16:14 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f5MLr-0003Xs-0n for emacs-devel@gnu.org; Sun, 08 Apr 2018 22:16:12 -0400 Original-Received: from mail-wm0-x22a.google.com ([2a00:1450:400c:c09::22a]:51089) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1f5MLq-0003Xa-Ks for emacs-devel@gnu.org; Sun, 08 Apr 2018 22:16:10 -0400 Original-Received: by mail-wm0-x22a.google.com with SMTP id t67so15199580wmt.0 for ; Sun, 08 Apr 2018 19:16:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=MScqvXUFTlt5rT16CkVL1hD7Z8HY60ngXSODi30Udhk=; b=CepFhhRyAjcOK9J2fewetzhC5RYFCKkav67rv7PCD6+NPq2IvdmzrF5Hw2m1x+WWNv vQqKv3l9nwJXoq/IZBWrpulpzbixLCCYdWA8wK7Mw9onQNlcD9qNUUSWX8eqYsV0rSZD tVyBbcl/fLBBkq2jbm7mFOqA6qwWwFm8SURjQAxT3SEPkb0zni4gcLTFb69HqcmV5g77 BmJAOcmhislUBXmOSCur+I42aJ2Z/OWc0XOWUR64rhTFGUm+pqEEAYtKZkHjHTTVSIUZ Zoi8jyp8IrSNl7AxQiN3LvFbzBUYRmbpSCbrk3Pr3UsPzuRXgyY2ZmNrpKZvZumKwpXi 90Qg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=MScqvXUFTlt5rT16CkVL1hD7Z8HY60ngXSODi30Udhk=; b=llrzZiuanpiBJa8QWIRj6z8Svi/QR8FuxS/KeQrAZv/sBofOPGV9IJnb9eB4mfL7hZ j9pH3+6shxqItFWqD2tae63FrFszNFs1JbWWSqBcYGCSDj3nj3UM+gzQKsg6r/dtwgXP 6fRwQNV4djAuo/xJ9x6E2FlqdAwMbvwFOMi/n+PN7FbqqSEBOknZPhSBFRXU+Cz0xpm7 vbUO5fQXaxNXqpFpCn4T5g3J+8XzQuwzEANSb5Aj7PKjQFlfCVpy/Nanx7FxoTjD+xsL bHZoBqVVu+LMO5cQl9miAzVavLUCPRGunHT2o8gIp+VJeAFHXNauFKG5JGz5YpZRi4pv irCw== X-Gm-Message-State: ALQs6tA5+kHszIXa+l6x0YnREXeiGmClqHvEQCLpu4Py1EqVllZe/Qst l/Qg5l45a1f/YzoyxuMlJ+VcYgTJVQivnKlsujQTWQ== X-Google-Smtp-Source: AIpwx4/hVDYqOwFJGeHH/7EQiumL6/yhqrSkk3bbUZZvNn99wztKV7cHOhoOW6w6yPCc0bu65SN15P2zNishs538JuM= X-Received: by 10.80.167.129 with SMTP id i1mr8687991edc.32.1523240169581; Sun, 08 Apr 2018 19:16:09 -0700 (PDT) Original-Received: by 10.80.203.195 with HTTP; Sun, 8 Apr 2018 19:16:08 -0700 (PDT) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::22a X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:224447 Archived-At: --94eb2c1956ea3743bc056960fd18 Content-Type: multipart/alternative; boundary="94eb2c1956ea3743b8056960fd16" --94eb2c1956ea3743b8056960fd16 Content-Type: text/plain; charset="UTF-8" IIUC the `(eq var cl--loop-accum-var)` is used to test whether the accumulation is `into` or not. If not, clauses like `collect(ing)` use a `cons-nreverse` rather than `nconc` algorithm, which is O(n) instead of O(n^2). Since we're doing `setcdr` in all cases where the accumulation is into a list, we're always O(n), so the optimization is unnecessary. Attached is a new patch that uses `(cl--loop-accum-var)`. On Sun, Apr 8, 2018 at 6:59 PM, Stefan Monnier wrote: > > Here's a second, cleaner attempt that separates the > `cl--loop-handle-accum` > > function into two functions, one to deal with lists and one to deal w/ > > non-lists. > > The tail-tracking optimizing is also applied to `append(ing)` and > > `nconc(ing)`. > > Thanks. Looks good. > I see you've dropped the (eq var cl--loop-accum-var) optimization. > Have you tried to measure the effect? > > > Stefan > > > > +(defun cl--loop-handle-accum (def) > [...] > > + (cond > [...] > > + (cl--loop-accum-var cl--loop-accum-var) > > You can write this line as just > > (cl--loop-accum-var) > > > -- Stefan > > > --94eb2c1956ea3743b8056960fd16 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
IIUC the `(eq var cl--loop-accum-var)` is used to test whe= ther the accumulation is `into` or not. If not, clauses like `collect(ing)`= use a `cons-nreverse` rather than `nconc` algorithm, which is O(n) instead= of O(n^2). Since we're doing `setcdr` in all cases where the accumulat= ion is into a list, we're always O(n), so the optimization is unnecessa= ry.

Attached is a new patch that uses `(cl--loop-accum-var)`.
On Sun, Apr 8, 2018 at 6:59 PM, Stefan Monnier = <monnier@iro.umontreal.ca> wrote:
> Here's a second, cleaner attempt t= hat separates the `cl--loop-handle-accum`
> function into two functions, one to deal with lists and one to deal w/=
> non-lists.
> The tail-tracking optimizing is also applied to `append(ing)` and
> `nconc(ing)`.

Thanks.=C2=A0 Looks good.
I see you've dropped the (eq var cl--loop-accum-var) optimization.
Have you tried to measure the effect?


=C2=A0 =C2=A0 =C2=A0 =C2=A0 Stefan


> +(defun cl--loop-handle-accum (def)
[...]
> +=C2=A0 (cond
[...]
> +=C2=A0 =C2=A0 (cl--loop-accum-var cl--loop-accum-var)

You can write this line as just

=C2=A0 =C2=A0 =C2=A0 =C2=A0(cl--loop-accum-var)


-- Stefan



--94eb2c1956ea3743b8056960fd16-- --94eb2c1956ea3743bc056960fd18 Content-Type: text/x-patch; charset="US-ASCII"; name="0003-Optimize-collect.into.patch" Content-Disposition: attachment; filename="0003-Optimize-collect.into.patch" Content-Transfer-Encoding: base64 X-Attachment-Id: f_jfrlummr0 RnJvbSBlNTZmZDg5YzU4MzgwMTMwMTFlNzI5ZTVhMjFmZjA3NDU4OGYyYWQyIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBUaWFueGlhbmcgWGlvbmcgPHRpYW54aWFuZy54aW9uZ0BnbWFp bC5jb20+CkRhdGU6IFN1biwgOCBBcHIgMjAxOCAxMjozNjo0MSAtMDcwMApTdWJqZWN0OiBbUEFU Q0hdIE9wdGltaXplIGBjb2xsZWN0Li4uaW50b2AKCkF2b2lkIE8obl4yKSBuY29uYy1pbmcgYnkg a2VlcGluZyB0cmFjayBvZiB0YWlsIG9mIGNvbGxlY3Rpb24uCi0tLQogbGlzcC9lbWFjcy1saXNw L2NsLW1hY3MuZWwgfCAxMTUgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLS0t LS0tLS0tCiAxIGZpbGUgY2hhbmdlZCwgNzcgaW5zZXJ0aW9ucygrKSwgMzggZGVsZXRpb25zKC0p CgpkaWZmIC0tZ2l0IGEvbGlzcC9lbWFjcy1saXNwL2NsLW1hY3MuZWwgYi9saXNwL2VtYWNzLWxp c3AvY2wtbWFjcy5lbAppbmRleCA5NjAwMjMwYzA3Li5iZDRjZTFhNjRiIDEwMDY0NAotLS0gYS9s aXNwL2VtYWNzLWxpc3AvY2wtbWFjcy5lbAorKysgYi9saXNwL2VtYWNzLWxpc3AvY2wtbWFjcy5l bApAQCAtMTUzNywzMSArMTUzNywzNCBAQCBjbC0tcGFyc2UtbG9vcC1jbGF1c2UKIAkocHVzaCBg KD49IChzZXRxICx0ZW1wICgxLSAsdGVtcCkpIDApIGNsLS1sb29wLWJvZHkpKSkKIAogICAgICAo KG1lbXEgd29yZCAnKGNvbGxlY3QgY29sbGVjdGluZykpCi0gICAgICAobGV0ICgod2hhdCAocG9w IGNsLS1sb29wLWFyZ3MpKQotCSAgICAodmFyIChjbC0tbG9vcC1oYW5kbGUtYWNjdW0gbmlsICdu cmV2ZXJzZSkpKQotCShpZiAoZXEgdmFyIGNsLS1sb29wLWFjY3VtLXZhcikKLQkgICAgKHB1c2gg YChwcm9nbiAocHVzaCAsd2hhdCAsdmFyKSB0KSBjbC0tbG9vcC1ib2R5KQotCSAgKHB1c2ggYChw cm9nbgotICAgICAgICAgICAgICAgICAgIChzZXRxICx2YXIgKG5jb25jICx2YXIgKGxpc3QgLHdo YXQpKSkKKyAgICAgIChsZXQgKCh3aGF0IChwb3AgY2wtLWxvb3AtYXJncykpKQorICAgICAgICAo Y2wtZGVzdHJ1Y3R1cmluZy1iaW5kICh2YXIgdmFyLXRhaWwpIChjbC0tbG9vcC1oYW5kbGUtbGlz dC1hY2N1bSBuaWwpCisgICAgICAgICAgKHB1c2ggYChwcm9nbgorICAgICAgICAgICAgICAgICAg IChpZiAobnVsbCAsdmFyLXRhaWwpCisgICAgICAgICAgICAgICAgICAgICAgIChzZXRxICx2YXIg KGxpc3QgLHdoYXQpICx2YXItdGFpbCAobGFzdCAsdmFyKSkKKyAgICAgICAgICAgICAgICAgICAg IChzZXRxICx2YXItdGFpbCAoc2V0Y2RyICx2YXItdGFpbCAobGlzdCAsd2hhdCkpKSkKICAgICAg ICAgICAgICAgICAgICB0KQogICAgICAgICAgICAgICAgIGNsLS1sb29wLWJvZHkpKSkpCiAKLSAg ICAgKChtZW1xIHdvcmQgJyhuY29uYyBuY29uY2luZyBhcHBlbmQgYXBwZW5kaW5nKSkKLSAgICAg IChsZXQgKCh3aGF0IChwb3AgY2wtLWxvb3AtYXJncykpCi0JICAgICh2YXIgKGNsLS1sb29wLWhh bmRsZS1hY2N1bSBuaWwgJ25yZXZlcnNlKSkpCi0JKHB1c2ggYChwcm9nbgotICAgICAgICAgICAg ICAgICAoc2V0cSAsdmFyCi0gICAgICAgICAgICAgICAgICAgICAgICwoaWYgKGVxIHZhciBjbC0t bG9vcC1hY2N1bS12YXIpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYChuY29uYwotICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgKCwoaWYgKG1lbXEgd29yZCAnKG5jb25jIG5jb25j aW5nKSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMnbnJldmVyc2UgIydy ZXZlcnNlKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICx3aGF0KQotICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgLHZhcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgYCgs KGlmIChtZW1xIHdvcmQgJyhuY29uYyBuY29uY2luZykpCi0gICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAjJ25jb25jICMnYXBwZW5kKQotICAgICAgICAgICAgICAgICAgICAgICAgICAg ICx2YXIgLHdoYXQpKSkKLSAgICAgICAgICAgICAgICAgdCkKLSAgICAgICAgICAgICAgY2wtLWxv b3AtYm9keSkpKQorICAgICAoKG1lbXEgd29yZCAnKGFwcGVuZCBhcHBlbmRpbmcpKQorICAgICAg KGxldCAoKHdoYXQgKHBvcCBjbC0tbG9vcC1hcmdzKSkpCisgICAgICAgIChjbC1kZXN0cnVjdHVy aW5nLWJpbmQgKHZhciB2YXItdGFpbCkgKGNsLS1sb29wLWhhbmRsZS1saXN0LWFjY3VtIG5pbCkK KyAgICAgICAgICAocHVzaCBgKHByb2duCisgICAgICAgICAgICAgICAgICAgKGlmIChudWxsICx2 YXItdGFpbCkKKyAgICAgICAgICAgICAgICAgICAgICAgKHNldHEgLHZhciAoY29weS1zZXF1ZW5j ZSAsd2hhdCkgLHZhci10YWlsIChsYXN0ICx2YXIpKQorICAgICAgICAgICAgICAgICAgICAgKHNl dHEgLHZhci10YWlsIChzZXRjZHIgLHZhci10YWlsIChjb3B5LXNlcXVlbmNlICx3aGF0KSkpKQor ICAgICAgICAgICAgICAgICAgIHQpCisgICAgICAgICAgICAgICAgY2wtLWxvb3AtYm9keSkpKSkK KworICAgICAoKG1lbXEgd29yZCAnKG5jb25jIG5jb25jaW5nKSkKKyAgICAgIChsZXQgKCh3aGF0 IChwb3AgY2wtLWxvb3AtYXJncykpKQorICAgICAgICAoY2wtZGVzdHJ1Y3R1cmluZy1iaW5kICh2 YXIgdmFyLXRhaWwpIChjbC0tbG9vcC1oYW5kbGUtbGlzdC1hY2N1bSBuaWwpCisgICAgICAgICAg KHB1c2ggYChwcm9nbgorICAgICAgICAgICAgICAgICAgIChpZiAobnVsbCAsdmFyLXRhaWwpCisg ICAgICAgICAgICAgICAgICAgICAgIChzZXRxICx2YXIgLHdoYXQgLHZhci10YWlsIChsYXN0ICx2 YXIpKQorICAgICAgICAgICAgICAgICAgICAgKHNldHEgLHZhci10YWlsIChzZXRjZHIgLHZhci10 YWlsICx3aGF0KSkpCisgICAgICAgICAgICAgICAgICAgdCkKKyAgICAgICAgICAgICAgICBjbC0t bG9vcC1ib2R5KSkpKQogCiAgICAgICgobWVtcSB3b3JkICcoY29uY2F0IGNvbmNhdGluZykpCiAg ICAgICAobGV0ICgod2hhdCAocG9wIGNsLS1sb29wLWFyZ3MpKQpAQCAtMTcyNiwyMiArMTcyOSw1 OCBAQCBjbC0tbG9vcC1sZXQKICAgICAgIGAoLChpZiBwYXIgJ2xldCAnbGV0KikKICAgICAgICAg LChuY29uYyAobnJldmVyc2UgdGVtcHMpIChucmV2ZXJzZSBuZXcpKSAsQGJvZHkpKSkpCiAKLShk ZWZ1biBjbC0tbG9vcC1oYW5kbGUtYWNjdW0gKGRlZiAmb3B0aW9uYWwgZnVuYykgOyB1c2VzIGxv b3AtKgotICAoaWYgKGVxIChjYXIgY2wtLWxvb3AtYXJncykgJ2ludG8pCi0gICAgICAobGV0ICgo dmFyIChjbC0tcG9wMiBjbC0tbG9vcC1hcmdzKSkpCi0JKG9yIChtZW1xIHZhciBjbC0tbG9vcC1h Y2N1bS12YXJzKQotCSAgICAocHJvZ24gKHB1c2ggKGxpc3QgKGxpc3QgdmFyIGRlZikpIGNsLS1s b29wLWJpbmRpbmdzKQotCQkgICAocHVzaCB2YXIgY2wtLWxvb3AtYWNjdW0tdmFycykpKQotCXZh cikKLSAgICAob3IgY2wtLWxvb3AtYWNjdW0tdmFyCi0JKHByb2duCi0JICAocHVzaCAobGlzdCAo bGlzdAotICAgICAgICAgICAgICAgICAgICAgICAoc2V0cSBjbC0tbG9vcC1hY2N1bS12YXIgKG1h a2Utc3ltYm9sICItLWNsLXZhci0tIikpCi0gICAgICAgICAgICAgICAgICAgICAgIGRlZikpCi0g ICAgICAgICAgICAgICAgY2wtLWxvb3AtYmluZGluZ3MpCi0JICAoc2V0cSBjbC0tbG9vcC1yZXN1 bHQgKGlmIGZ1bmMgKGxpc3QgZnVuYyBjbC0tbG9vcC1hY2N1bS12YXIpCi0gICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgY2wtLWxvb3AtYWNjdW0tdmFyKSkKLQkgIGNsLS1sb29wLWFj Y3VtLXZhcikpKSkKKyhkZWZ1biBjbC0tbG9vcC1oYW5kbGUtbGlzdC1hY2N1bSAoZGVmKQorICAi SGFuZGxlIGxpc3QgdmFsdWUgYWNjdW11bGF0aW9uIGNsYXVzZS4KKworREVGIGlzIHRoZSBpbml0 aWFsIHZhbHVlIG9mIHRoZSBhY2N1bXVsYXRpb24gdmFyaWFibGUuCisKK1JldHVybnMgKFZBUiBW QVItVEFJTCksIHdoZXJlIFZBUiBpcyB0aGUgYWNjdW11bGF0aW9uIHZhcmlhYmxlCithbmQgVkFS LVRBSUwgaXMgdGhlIHRhaWwgb2YgdGhlIGFjY3VtdWxhdG9yLiIKKyAgKGNsLWZsZXQgKCh0YWls LXN5bWJvbCAodmFyKQorICAgICAgICAgICAgICAoZ2Vuc3ltIChjb25jYXQgKHN5bWJvbC1uYW1l IHZhcikgIi10YWlsLSIpKSkpCisgICAgKGNvbmQKKyAgICAgICgoZXEgKGNhciBjbC0tbG9vcC1h cmdzKSAnaW50bykKKyAgICAgICAobGV0KiAoKHZhciAoY2wtLXBvcDIgY2wtLWxvb3AtYXJncykp CisgICAgICAgICAgICAgICh2YXItdGFpbCAodGFpbC1zeW1ib2wgdmFyKSkpCisgICAgICAgICAo aWYgKG1lbXEgdmFyIGNsLS1sb29wLWFjY3VtLXZhcnMpCisgICAgICAgICAgICAgKHB1c2ggYCgo LHZhci10YWlsICwobGFzdCBkZWYpKSkgY2wtLWxvb3AtYmluZGluZ3MpCisgICAgICAgICAgIChw dXNoIGAoKCx2YXIgLGRlZikpIGNsLS1sb29wLWJpbmRpbmdzKQorICAgICAgICAgICAocHVzaCBg KCgsdmFyLXRhaWwgLChsYXN0IGRlZikpKSBjbC0tbG9vcC1iaW5kaW5ncykKKyAgICAgICAgICAg KHB1c2ggdmFyIGNsLS1sb29wLWFjY3VtLXZhcnMpKQorICAgICAgICAgKGxpc3QgdmFyIHZhci10 YWlsKSkpCisKKyAgICAgIChjbC0tbG9vcC1hY2N1bS12YXIKKyAgICAgICBgKCxjbC0tbG9vcC1h Y2N1bS12YXIgLCh0YWlsLXN5bWJvbCBjbC0tbG9vcC1hY2N1bS12YXIpKSkKKworICAgICAgKHQg KGxldCogKCh2YXIgKG1ha2Utc3ltYm9sICItLWNsLXZhci0tIikpCisgICAgICAgICAgICAgICAg KHZhci10YWlsICh0YWlsLXN5bWJvbCB2YXIpKSkKKyAgICAgICAgICAgKHB1c2ggYCgoLHZhciAs ZGVmKSkgY2wtLWxvb3AtYmluZGluZ3MpCisgICAgICAgICAgIChwdXNoIGAoKCx2YXItdGFpbCAs KGxhc3QgZGVmKSkpIGNsLS1sb29wLWJpbmRpbmdzKQorICAgICAgICAgICAoc2V0cSBjbC0tbG9v cC1hY2N1bS12YXIgdmFyCisgICAgICAgICAgICAgICAgIGNsLS1sb29wLXJlc3VsdCB2YXIpCisg ICAgICAgICAgIChsaXN0IHZhciB2YXItdGFpbCkpKSkpKQorCisoZGVmdW4gY2wtLWxvb3AtaGFu ZGxlLWFjY3VtIChkZWYpCisgICJIYW5kbGUgbm9uLWxpc3QgdmFsdWUgYWNjdW11bGF0aW9uIGNs YXVzZS4KKworREVGIGlzIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBhY2N1bXVsYXRpb24gdmFy aWFibGUuCisKK1JldHVybnMgdGhlIGFjY3VtdWxhdGlvbiB2YXJpYWJsZSBWQVIuIgorICAoY29u ZAorICAgICgoZXEgKGNhciBjbC0tbG9vcC1hcmdzKSAnaW50bykKKyAgICAgKGxldCogKCh2YXIg KGNsLS1wb3AyIGNsLS1sb29wLWFyZ3MpKSkKKyAgICAgICAodW5sZXNzIChtZW1xIHZhciBjbC0t bG9vcC1hY2N1bS12YXJzKQorICAgICAgICAgKHB1c2ggYCgoLHZhciAsZGVmKSkgY2wtLWxvb3At YmluZGluZ3MpCisgICAgICAgICAocHVzaCB2YXIgY2wtLWxvb3AtYWNjdW0tdmFycykpCisgICAg ICAgdmFyKSkKKworICAgIChjbC0tbG9vcC1hY2N1bS12YXIpCisKKyAgICAodCAobGV0KiAoKHZh ciAobWFrZS1zeW1ib2wgIi0tY2wtdmFyLS0iKSkpCisgICAgICAgICAocHVzaCBgKCgsdmFyICxk ZWYpKSBjbC0tbG9vcC1iaW5kaW5ncykKKyAgICAgICAgIChzZXRxIGNsLS1sb29wLWFjY3VtLXZh ciB2YXIKKyAgICAgICAgICAgICAgIGNsLS1sb29wLXJlc3VsdCB2YXIpCisgICAgICAgICB2YXIp KSkpCiAKIChkZWZ1biBjbC0tbG9vcC1idWlsZC1hbmRzIChjbGF1c2VzKQogICAiUmV0dXJuIHZh cmlvdXMgcmVwcmVzZW50YXRpb25zIG9mIChhbmQgLiBDTEFVU0VTKS4KLS0gCjIuMTQuMwoK --94eb2c1956ea3743bc056960fd18--