From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Daniel Pittman Newsgroups: gmane.emacs.devel Subject: `process-send-*` performance seems ... bad? Date: Tue, 18 Jun 2019 17:41:22 -0400 Message-ID: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="0000000000007d2eef058b9ffb76" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="206493"; mail-complaints-to="usenet@blaine.gmane.org" To: emacs-devel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Jun 18 23:56:25 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1hdM5Y-000rd9-64 for ged-emacs-devel@m.gmane.org; Tue, 18 Jun 2019 23:56:24 +0200 Original-Received: from localhost ([::1]:33692 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hdM5X-0006gc-5s for ged-emacs-devel@m.gmane.org; Tue, 18 Jun 2019 17:56:23 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:42883) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hdM32-0005Yr-Dw for emacs-devel@gnu.org; Tue, 18 Jun 2019 17:53:51 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hdLrf-0007Uf-9f for emacs-devel@gnu.org; Tue, 18 Jun 2019 17:42:04 -0400 Original-Received: from mail-lj1-x232.google.com ([2a00:1450:4864:20::232]:33646) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hdLre-0007N3-Pi for emacs-devel@gnu.org; Tue, 18 Jun 2019 17:42:03 -0400 Original-Received: by mail-lj1-x232.google.com with SMTP id h10so1116218ljg.0 for ; Tue, 18 Jun 2019 14:42:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=7PbZp514WrxRYSCHcI5HN4xoKPIdQj8qEeCAspQJ1/U=; b=rkVVzfpXrunML5OrEi8QJF+89RNpFnUBzJR5lSW2gwgAveTDS9wOV0BVgUl4E9KUHp MH98AZFbAJAiLRRoit44LFEMtpbACdmYgWlLwGGyOB12Xgy7CRnzQA1zvfx5WUFYZ8Si DfxzOCNYHv7QI3n6DeVByjYOOHa9Wl1h31yY+lcAfHjizjo5O9whHRTS4Y+i5J91CICW a1NAxvYZFFlyaMa6Thur47GGxvvPJ75uAD0yYopORfY1iTK0LyWEwIc64yD+eo/2hBLN 0DAtU6Fe/gHPvWW/2HAdCmvaCyS424AxJfKVMwrBWtSqkPG+HdWUu34x9LVS3IY2qc1z jN2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=7PbZp514WrxRYSCHcI5HN4xoKPIdQj8qEeCAspQJ1/U=; b=IMNBbE+LaGH+GQsqYpctmzdYbtHf5wexrLd3CLUfUDc9D7fgQg5hA5KtG202NNUhqb 3ssV8sXFoDXPw2svVluNmcetqK6CWYx4bGLIDVY2+ehNCenHxSHn0eXS/QUEvgpaRF/c S+QdvPuD9dTja96xS/35BOFNNkYfWrexZlt7zk4i0hjkLsfNmFgH7TebChlpsGxSfq6F Szi1smxv+jFZsHiYh9IpoXeYp0OZ5maA1AmE/nX36NcFcJ6HtL0Peocpo1+yv1PIpgzS EoxOiDnQzJl7M7866l64QGwnZL9RJzW6lJj2bTm40PXzybXPlDW4P5HJ9VzwPG57ZQqP Avjg== X-Gm-Message-State: APjAAAW7GBs63DXkNb1QcO/CwDw2Hz202EeQi87yPeGpPHaqCGA/wtPv KmNgGSbfPbA1aCeyjXVNO2x4Ik8tqcSIkswHeu0/n07VMw1lwA== X-Google-Smtp-Source: APXvYqwu3yDItaf4K/gH86emxw1seF+CkaXVMP80FOdl3UG41JaJyUY0A6YzNeCS1fs5TUG7WIBqq5zNkDhMbI+ZcTM= X-Received: by 2002:a2e:9b48:: with SMTP id o8mr17146149ljj.122.1560894118862; Tue, 18 Jun 2019 14:41:58 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::232 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 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:237872 Archived-At: --0000000000007d2eef058b9ffb76 Content-Type: multipart/alternative; boundary="0000000000007d2eeb058b9ffb74" --0000000000007d2eeb058b9ffb74 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable G'day. I've been trying to work out of the fzf "fuzzy finder" system could be used effectively within Emacs; it has the closest to "right" algorithm. Unfortunately it is written in Go, and the upstream are not interested in making it usable as either a pipe-process ala ispell pipe mode, or as a library so that such a front-end could be developed. It does support batch matching, though, by invoking the command with the filter string, and sending the possible completions through it. Given that, I figured I'd test it out and see if the cost of running that external process was too high. The problem seems to be that Emacs writes (or reads) from the piped process unreasonably slowly. Output to a buffer, or a process filter (#'ignore) seems to make no difference, so I'm assuming the write performance rather than read-and-store performance is the issue. My question here is: is there something I'm doing wrong, or is this the very best I could expect from Emacs with an external process? Emacs itself is built from git at commit 44a086e, and doesn't have debugging stuff enabled or whatever. macOS x86-64 system. Have not tested on GNU/Linux or anything at this time. It doesn't look to me like pipes are inherently the problem on the platform, given this testing shows that the same test command in the same situation (pipe input and output) performs significantly faster that Emacs will in the tests following: ] mkfifo in out ] cat obarray.data > in & wc < out & time fzf -f "hook mode" < in > out ; wait [1] 45534 [2] 45535 [1] - 45534 done gunzip -c obarray.data.gz > in 604 604 15841 fzf -f "hook mode" < in > out 0.05s user 0.01s system 184% cpu 0.033 total [2] + 45535 done wc < out ] wc obarray.data 59176 59708 955548 obarray.data Use of named pipes and cat to ensure with certainty we had the same basic throughput model without, eg, the shell doing something too smart or whatever. That obarray.data file contains the result of inserting all symbols in the default obarray in my Emacs into a file, newline separated, and then saving it. This is a hard, but not impossible, test of the filtering system I think, intended to show bottlenecks. Smaller data sets were second in line to test, but... Unfortunately Emacs performance is shockingly slow; all code is byte-compiled and warmed up before the benchmark tests are run. This is the result of 5 warmup rounds, followed by 10 measured rounds, through the external process. GC effectively disabled, and forced before each benchmark pass, to avoid that shaking things up. Note that the cost of fzf is ~ 0.05s, so we attribute best case 1.747 seconds to Emacs. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D pass 1 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D write-with-temp-buffer: 5.1272s with 0 GCs taking 0.0000s: (5.127218 0 0.0) write-with-two-calls: 1.9974s with 0 GCs taking 0.0000s: (1.99745 0 0.0) write-with-one-call: 1.6549s with 0 GCs taking 0.0000s: (1.6549049999999998 0 0.0) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D pass 2 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D write-with-temp-buffer: 5.0828s with 0 GCs taking 0.0000s: (5.082764 0 0.0) write-with-two-calls: 2.0536s with 0 GCs taking 0.0000s: (2.053559 0 0.0) write-with-one-call: 1.7901s with 0 GCs taking 0.0000s: (1.790106 0 0.0) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D pass 3 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D write-with-temp-buffer: 5.1175s with 0 GCs taking 0.0000s: (5.117541 0 0.0) write-with-two-calls: 2.1159s with 0 GCs taking 0.0000s: (2.115893 0 0.0) write-with-one-call: 1.7970s with 0 GCs taking 0.0000s: (1.797042 0 0.0) The code behind those results is attached, and the obarray content is available on request =E2=80=93 it is still 375k gzipped, and isn't particul= arly interesting, as most any "production" Emacs instance will have a large enough obarray to be interesting. I also pre-calculate the set of strings, to avoid that being part of the benchmark; handling the output is also skipped for the same reason. Using `tail -n 604` to get roughly the same amount of output, and to force the command to run identically (ie: consume all input before output) makes no difference, as expected given the observed performance of fzf above. (middle run, others identical and omitted for brevity.) write-with-temp-buffer: 5.4254s with 0 GCs taking 0.0000s: (5.425443 0 0.0) write-with-two-calls: 2.3092s with 0 GCs taking 0.0000s: (2.309152 0 0.0) write-with-one-call: 2.0219s with 0 GCs taking 0.0000s: (2.021912 0 0.0) Using a newline rather than null byte delimiter makes no difference, as you would probably expect. Using a list rather than a vector for `data`, the input, makes the temp buffer case ~ 1.3 seconds faster consistently, but the other two cases ... roughly equally, maybe a fraction slower, but this is adhoc enough that I think it is not statistically significant. Thanks. --0000000000007d2eeb058b9ffb74 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
G'day.=C2=A0 I've been trying to work out of the f= zf "fuzzy finder" system could be used effectively within Emacs; = it has the closest to "right" algorithm.=C2=A0=C2=A0

Unfortunately it is written in Go, and the upstream are not interest= ed in making it usable as either a pipe-process ala ispell pipe mode, or as= a library so that such a front-end could be developed.

It does support batch matching, though, by invoking the command with = the filter string, and sending the possible completions through it.=C2=A0 G= iven that, I figured I'd test it out and see if the cost of running tha= t external process was too high.=C2=A0=C2=A0

The p= roblem seems to be that Emacs writes (or reads) from the piped process unre= asonably slowly.=C2=A0 Output to a buffer, or a process filter (#'ignor= e) seems to make no difference, so I'm assuming the write performance r= ather than read-and-store performance is the issue.

My question here is: is there something I'm doing wrong, or is this t= he very best I could expect from Emacs with an external process?
=
Emacs itself is built from git at commit 44a086e, and doesn&= #39;t have debugging stuff enabled or whatever.=C2=A0 macOS x86-64 system.= =C2=A0 Have not tested on GNU/Linux or anything at this time.=C2=A0=C2=A0

It doesn't look to me like pipes are inherently= the problem on the platform, given this testing shows that the same test c= ommand in the same situation (pipe input and output) performs significantly= faster that Emacs will in the tests following:

] = mkfifo in out
] cat obarray.data > in & wc < out & time = fzf -f "hook mode" < in > out ; wait
[1] 45534
[2] 45= 535
[1] =C2=A0- 45534 done =C2=A0 =C2=A0 =C2=A0 gunzip -c obarray.data.g= z > in
=C2=A0 =C2=A0 =C2=A0604 =C2=A0 =C2=A0 604 =C2=A0 15841
fzf = -f "hook mode" < in > out =C2=A00.05s user 0.01s system 184= % cpu 0.033 total
[2] =C2=A0+ 45535 done =C2=A0 =C2=A0 =C2=A0 wc &l= t; out
] wc obarray.data
=C2=A0 =C2=A059176 =C2=A0 = 59708 =C2=A0955548 obarray.data

Use of named p= ipes and cat to ensure with certainty we had the same basic throughput mode= l without, eg, the shell doing something too smart or whatever.
<= br>
That obarray.data file contains the result of inserting all s= ymbols in the default obarray in my Emacs into a file, newline separated, a= nd then saving it.=C2=A0 This is a hard, but not impossible, test of the fi= ltering system I think, intended to show bottlenecks.=C2=A0 Smaller data se= ts were second in line to test, but...

Unfortunate= ly Emacs performance is shockingly slow; all code is byte-compiled and warm= ed up before the benchmark tests are run.=C2=A0 This is the result of 5 war= mup rounds, followed by 10 measured rounds, through the external process.= =C2=A0 GC effectively disabled, and forced before each benchmark pass, to a= void that shaking things up.

Note that the cost of= fzf is ~ 0.05s, so we attribute best case=C2=A01.747 seconds to Emacs.

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D pass 1 =3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D
write-with-temp-buffer: 5.1272s with 0 GCs taking 0.0000= s: (5.127218 0 0.0)
write-with-two-calls: 1.9974s with 0 GCs taking 0.00= 00s: (1.99745 0 0.0)
write-with-one-call: 1.6549s with 0 GCs taking 0.00= 00s: (1.6549049999999998 0 0.0)
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D pass 2 = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
write-with-temp-buffer: 5.0828s with 0 GC= s taking 0.0000s: (5.082764 0 0.0)
write-with-two-calls: 2.0536s with 0 = GCs taking 0.0000s: (2.053559 0 0.0)
write-with-one-call: 1.7901s with 0= GCs taking 0.0000s: (1.790106 0 0.0)
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D pas= s 3 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
write-with-temp-buffer: 5.1175s with = 0 GCs taking 0.0000s: (5.117541 0 0.0)
write-with-two-calls: 2.1159s wit= h 0 GCs taking 0.0000s: (2.115893 0 0.0)
write-with-one-call: 1.7970s wi= th 0 GCs taking 0.0000s: (1.797042 0 0.0)

The = code behind those results is attached, and the obarray content is available= on request =E2=80=93 it is still 375k gzipped, and isn't particularly = interesting, as most any "production" Emacs instance will have a = large enough obarray to be interesting.=C2=A0=C2=A0

I also pre-calculate the set of strings, to avoid that being=C2=A0part of= the benchmark; handling the output is also skipped for the same reason.

Using `tail -n 604` to get roughly the same amount o= f output, and to force the command to run identically (ie: consume all inpu= t before output) makes no difference, as expected given the observed perfor= mance of fzf above.=C2=A0 (middle run, others identical and omitted for bre= vity.)

write-with-temp-buffer: 5.4254s with 0 GCs = taking 0.0000s: (5.425443 0 0.0)
write-with-two-calls: 2.3092s with 0 GC= s taking 0.0000s: (2.309152 0 0.0)
write-with-one-call: 2.0219s with 0 G= Cs taking 0.0000s: (2.021912 0 0.0)

Using a newline rathe= r than null byte delimiter makes no difference, as you would probably expec= t.=C2=A0 Using a list rather than a vector for `data`, the input, makes the= temp buffer case ~ 1.3 seconds faster consistently, but the other two case= s ... roughly equally, maybe a fraction slower, but this is adhoc enough th= at I think it is not statistically significant.

Th= anks.
--0000000000007d2eeb058b9ffb74-- --0000000000007d2eef058b9ffb76 Content-Type: application/octet-stream; name="fzf-benchmark.el" Content-Disposition: attachment; filename="fzf-benchmark.el" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_jx2bqbva0 OzsgLSotIGxleGljYWwgLSotCihsZXQqICgoZ2MtY29ucy1wZXJjZW50YWdlIG1vc3QtcG9zaXRp dmUtZml4bnVtKQogICAgICAgKGdjLWNvbnMtdGhyZXNob2xkIG1vc3QtcG9zaXRpdmUtZml4bnVt KQogICAgICAgKGZuCiAgICAgICAgKGxhbWJkYSAod3JpdGVyKQogICAgICAgICAgKGxldCAoKGRl ZmF1bHQtZGlyZWN0b3J5CiAgICAgICAgICAgICAgICAgICIvZ3NzaDpzbGlwcHljaGVlemUuYy5n b29nbGVycy5jb206L2dvb2dsZS9zcmMvY2xvdWQvc2xpcHB5Y2hlZXplL3dvcmsvZ29vZ2xlMy9w cm9kdWN0aW9uL3N0b3JhZ2UvY2hyb25pY2xlLyIpCiAgICAgICAgICAgICAgICAocHJvY2Vzcy1h ZGFwdGl2ZS1yZWFkLWJ1ZmZlcmluZyB0KQogICAgICAgICAgICAgICAgc3Rkb3V0IHN0ZGVyciBw cm9jKQogICAgICAgICAgICAodW53aW5kLXByb3RlY3QKICAgICAgICAgICAgICAgIChwcm9nbgog ICAgICAgICAgICAgICAgICA7OyBkb25lIGhlcmUgYmVjYXVzZSB3ZSBuZWVkIHRvIHNhZmVseSB1 bndpbmQgaWYgZ2VuZXJhdGUtbmV3LWJ1ZmZlcgogICAgICAgICAgICAgICAgICA7OyBmYWlscyB0 aGUgc2Vjb25kIHRpbWUsIGJ1dCBub3QgdGhlIGZpcnN0LgogICAgICAgICAgICAgICAgICAoc2V0 cSBzdGRvdXQgKGdlbmVyYXRlLW5ldy1idWZmZXIgIiAqZnpmLXN0ZG91dCoiKQogICAgICAgICAg ICAgICAgICAgICAgICBzdGRlcnIgKGdlbmVyYXRlLW5ldy1idWZmZXIgIiAqZnpmLXN0ZGVycioi KQogICAgICAgICAgICAgICAgICAgICAgICBwcm9jIChtYWtlLXByb2Nlc3MgOm5hbWUgImZ6Zi1m b3ItYmVuY2htYXJrIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg OmJ1ZmZlciBzdGRvdXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IDpzdGRlcnIgc3RkZXJyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICA6c2VudGluZWwgIydpZ25vcmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIDs7IDpjb21tYW5kICcoImZ6ZiIgIi0tcmVhZDAiICItLXByaW50MCIgIi1mIiAiaG9v ayBtb2RlIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDpjb21t YW5kICcoInRhaWwiICItbiIgIjYwNCIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICA6Y29kaW5nICd1dGYtOC1hdXRvCiAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICA6bm9xdWVyeSB0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICA6Y29ubmVjdGlvbi10eXBlICdwaXBlKSkKICAgICAgICAgICAgICAgICAg KGZ1bmNhbGwgd3JpdGVyIHByb2MpCiAgICAgICAgICAgICAgICAgIChwcm9jZXNzLXNlbmQtZW9m IHByb2MpCiAgICAgICAgICAgICAgICAgIDs7IHdhaXQgZm9yIGNvbXBsZXRpb24KICAgICAgICAg ICAgICAgICAgKHdoaWxlIChhY2NlcHQtcHJvY2Vzcy1vdXRwdXQgcHJvYyAxKSkKICAgICAgICAg ICAgICAgICAgOzsgdGhpcyBpcyB3aGVyZSB3ZSB3b3VsZCBwYXJzZSBhbmQgcmV0dXJuIHJlc3Vs dHMsIGJ1dCBmb3IgYmVuY2htYXJraW5nIHdlIHNraXAgdGhhdC4KICAgICAgICAgICAgICAgICAg KSkKICAgICAgICAgICAgKHByb2duCiAgICAgICAgICAgICAgKHdoZW4gKHByb2Nlc3MtbGl2ZS1w IHByb2MpCiAgICAgICAgICAgICAgICAoa2lsbC1wcm9jZXNzIHByb2MgdCkpCiAgICAgICAgICAg ICAgKHdoZW4gKGFuZCBzdGRvdXQgKGJ1ZmZlci1uYW1lIHN0ZG91dCkpCiAgICAgICAgICAgICAg ICAoa2lsbC1idWZmZXIgc3Rkb3V0KSkKICAgICAgICAgICAgICAod2hlbiAoYW5kIHN0ZGVyciAo YnVmZmVyLW5hbWUgc3RkZXJyKSkKICAgICAgICAgICAgICAgIChraWxsLWJ1ZmZlciBzdGRlcnIp KSkpKSkKICAgICAgIChkYXRhIChsZXQgKHRtcCkKICAgICAgICAgICAgICAgKG1hcGF0b21zIChs YW1iZGEgKHN5bWJvbCkgKHNldHEgdG1wIChjb25zIChzeW1ib2wtbmFtZSBzeW1ib2wpIHRtcCkp KSkKICAgICAgICAgICAgICAgKGFwcGx5ICMndmVjdG9yIChyZXZlcnNlIHRtcCkpKSkKICAgICAg ICh3cml0ZS13aXRoLXRlbXAtYnVmZmVyIChsYW1iZGEgKHByb2MpCiAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICh3aXRoLXRlbXAtYnVmZmVyCiAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgKG1hcGMgKGxhbWJkYSAoY2hvaWNlKSAoaW5zZXJ0IGNob2ljZSAiXDAiKSkg ZGF0YSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocHJvY2Vzcy1zZW5kLXJl Z2lvbiBwcm9jIChwb2ludC1taW4pIChwb2ludC1tYXgpKSkpKQogICAgICAgKHdyaXRlLXdpdGgt dHdvLWNhbGxzIChsYW1iZGEgKHByb2MpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAo bWFwYyAobGFtYmRhIChjaG9pY2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIChwcm9jZXNzLXNlbmQtc3RyaW5nIHByb2MgY2hvaWNlKQogICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAocHJvY2Vzcy1zZW5kLXN0cmluZyBwcm9jICJcMCIpKQogICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSkpKQogICAgICAgKHdyaXRlLXdp dGgtb25lLWNhbGwgKGxhbWJkYSAocHJvYykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg KG1hcGMgKGxhbWJkYSAoY2hvaWNlKSAocHJvY2Vzcy1zZW5kLXN0cmluZyBwcm9jIChmb3JtYXQg IiVzXDAiIGNob2ljZSkpKSBkYXRhKSkpKQogIDs7IChkZWJ1ZykKICA7OyAoZnVuY2FsbCBmbiB3 cml0ZS13aXRoLXRlbXAtYnVmZmVyKQogIChsZXQgKChjb21waWxlZC1mbiAoYnl0ZS1jb21waWxl IGZuKSkpCiAgICAod2l0aC1jdXJyZW50LWJ1ZmZlci13aW5kb3cgImZ6ZiBiZW5jaG1hcmsgcmVz dWx0cyIgbmlsIG5pbAogICAgICAocG9wLXRvLWJ1ZmZlciAoY3VycmVudC1idWZmZXIpKQogICAg ICAoZG90aW1lcyAocGFzcyAzKQogICAgICAgIChpbnNlcnQgKGZvcm1hdCAiPT09PT09PT09PSBw YXNzICVkID09PT09PT09PT0iICgxKyBwYXNzKSkgIlxuIikKICAgICAgICAobWFwYyAobGFtYmRh ICh0ZXN0KQogICAgICAgICAgICAgICAgKGxldCogKCh0ZXN0Zm4gKGJ5dGUtY29tcGlsZSAoc3lt Ym9sLXZhbHVlIHRlc3QpKSkKICAgICAgICAgICAgICAgICAgICAgICA7OyB3YXJtIHVwIHRoZSBm dW5jdGlvbi4KICAgICAgICAgICAgICAgICAgICAgICAoZ2FyYmFnZS1jb2xsZWN0KQogICAgICAg ICAgICAgICAgICAgICAgICh3YXJtdXAgKGRvdGltZXMgKHdhcm11cC1jb3VudGVyIDUpIChmdW5j YWxsIGNvbXBpbGVkLWZuIHRlc3RmbikpKQogICAgICAgICAgICAgICAgICAgICAgIChnYXJiYWdl LWNvbGxlY3QpCiAgICAgICAgICAgICAgICAgICAgICAgKHJlc3VsdCAoYmVuY2htYXJrLXJ1biAx MCAoZnVuY2FsbCBjb21waWxlZC1mbiB0ZXN0Zm4pKSkpCiAgICAgICAgICAgICAgICAgIChpbnNl cnQgKGZvcm1hdCAiJTE4czogJS40ZnMgd2l0aCAlZCBHQ3MgdGFraW5nICUuNGZzOiAlcyIgdGVz dCAobnRoIDAgcmVzdWx0KSAobnRoIDEgcmVzdWx0KSAobnRoIDIgcmVzdWx0KSByZXN1bHQpICJc biIpKSkKICAgICAgICAgICAgICAnKHdyaXRlLXdpdGgtdGVtcC1idWZmZXIgd3JpdGUtd2l0aC10 d28tY2FsbHMgd3JpdGUtd2l0aC1vbmUtY2FsbCkpKQogICAgICAoZ290by1jaGFyIChwb2ludC1t aW4pKSkpKQo= --0000000000007d2eef058b9ffb76--