From: Eric Mahurin Date: 2006-09-27T14:08:03+09:00 Subject: Re: Array shift bug ------=_Part_15662_16317407.1159333680122 Content-Type: multipart/alternative; boundary="----=_Part_15663_6296557.1159333680122" ------=_Part_15663_6296557.1159333680122 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline On 9/26/06, Yukihiro Matsumoto wrote: > > Hi, > > In message "Re: Array shift bug" > on Mon, 25 Sep 2006 12:37:20 +0900, "Eric Mahurin" < > eric.mahurin@gmail.com> writes: > > |Here is a quick summary of what I did: > > > > I just submitted a patch based on yours to the HEAD. Thank you! > It is fairly complex, so that I won't submit it to the stable (1.8). > > |These same techniques (or something like them) could be applied to String > |also. > > Since strings have no shift nor unshift, I am not going to add it to > the strings, until it is really needed. > > Thank you again. And I apologize that I left your patch ignored for a > full year. > > matz. > > Thanks matz, I tried out the code and it looks better in a few spots, but it also got worse in a few (but not as common). You can still use enormous amounts of memory because of the copy-on-write mechanism. I am attaching a testbench for testing runtime and memory (sorry, linux only) performance for a bunch of array operations that can be O(1). It also includes some new tests at the end (didn't have these before) that show O(n**2) memory when it should be O(n). All of those performance (memory and runtime) issues were fixed in my patch. Here are the results (for just 2^12=4096 iterations/elements): + : improved - : needs work, still not to O(1) * : partially improved, still not to O(1) -- : worse code 2006-09-01 2006-09-26 eric's-patch ---- ----------- ----------- ------------ sec kB sec kB sec kB ---- ---- ---- ---- ---- ---- ; 0.01 132 0.00 0 0.01 136 shift 0.01 148 0.00 132 0.00 144 shift(1) 0.01 152 0.13- 136 0.01 152 pop 0.01 128 0.01 132 0.01 144 pop(1) 0.01 152 0.00 136 0.01 152 shift;pop 0.01 132 0.01 136 0.01 156 shift(1);pop(1) 0.01 136 0.14- 140 0.01 164 unshift(i) 0.13 132 0.01+ 140 0.00 132 push(i) 0.01 132 0.01 0 0.01 132 unshift(i);push(i) 0.14 0 0.00+ 200 0.01 208 unshift(shift) 0.59 4816 0.00+ 0 0.01 140 unshift(*shift(1)) 0.60 4816 0.13* 68 0.01 148 push(pop) 0.01 132 0.00 0 0.01 140 push(*pop(1)) 0.38 4816 0.00+ 8 0.01 148 push(shift) 0.45 4816 0.00+ 0 0.01 140 push(*shift(1)) 0.45 4816 0.14* 8 0.01 148 unshift(pop) 0.14 132 0.00+ 60 0.01 140 unshift(*pop(1)) 0.51 4816 0.01+ 68 0.01 148 slice!(1) 0.13 148 0.56-- 132 0.00 144 delete_at(1) 0.14 148 0.55-- 132 0.00 144 slice!(1,1) 0.58 8124 0.58- 8264 0.01 152 self[1,1]=[] 0.14 552 0.13- 536 0.01 548 slice!(-2) 0.00 148 0.00 132 0.00 144 delete_at(-2) 0.00 148 0.00 132 0.00 144 slice!(-2,1) 0.45 8120 0.46- 8260 0.01 148 self[-2,1]=[] 0.01 544 0.01 528 0.00 544 self[1,0]=[i] 0.16 140 0.14- 4 0.00 304 insert(1,i) 0.16 136 0.14- 0 0.00 304 self[-1,0]=[i] 0.02 136 0.01 4 0.01 308 insert(-2,i) 0.02 132 0.01 0 0.01 308 self[1,0]=slice!(1,1) 0.76 4056 0.77- 3956 0.01 144 insert(1,delete_at(1)) 0.27 136 0.81-- 4 0.01 144 self[-1,0]=slice!(-2,1) 0.56 4056 0.58 3956 0.02 144 insert(-2,delete_at(-2)) 0.01 136 0.01 4 0.01 144 self[-1,0]=slice!(1,1) 0.73 4052 0.69- 3952 0.01 276 insert(-2,delete_at(1)) 0.13 132 0.63-- 0 0.01 276 self[1,0]=slice!(-2,1) 0.72 4052 0.74- 3952 0.01 212 insert(1,delete_at(-2)) 0.17 132 0.17- 0 0.01 212 self[i]=self[i] 0.00 136 0.00 4 0.01 140 self[i]=at(i) 0.00 136 0.01 4 0.00 140 self[i,1]=self[i,1] 0.50 3960 0.50- 3952 0.01 144 self[-i-1]=self[-i-1] 0.01 140 0.01 8 0.02 144 self[-i-1]=at(-i-1) 0.02 140 0.01 8 0.01 144 self[-i-1,1]=self[-i-1,1] 0.49 4056 0.50- 3956 0.01 144 self[-i-1]=self[i] 0.01 132 0.01 0 0.01 136 self[-i-1]=at(i) 0.01 132 0.01 0 0.01 136 self[-i-1,1]=self[i,1] 0.57 4044 0.59- 3948 0.01 140 self[i]=self[-i-1] 0.01 136 0.01 4 0.01 140 self[i]=at(-i-1) 0.01 136 0.01 4 0.01 140 self[i,1]=self[-i-1,1] 0.56 4048 0.59- 3952 0.02 140 push(shift(1)) 8.15 393900 0.24* 4 0.02 312 unshift(pop(1)) 4.80 393920 0.01+ 60 0.02 308 insert(-1,slice!(0,1)) 6.05 262964 36.24- 262836 0.04 404 insert(0,slice!(-1,1)) 2.71 262980 73.98- 262852 0.03 304 self[i]=self[i,1] 9.84 262924 18.77- 262832 0.02 268 self[-i-1]=self[-i-1,1] 8.36 262976 39.82- 262820 0.03 272 self[-i-1]=self[i,1] 5.94 262840 38.00- 262816 0.03 132 self[i]=self[-i-1,1] 0.90 262824 19.97- 262800 0.03 136 Notice how bad the memory and runtime is for these last ones. And this is only for 4096 elements/iterations! I think the rest of array.c should be overhauled just like I had to do in my original patch. I still would like to see the same done for String sometime. The same issues exist. You'll find many deficiencies even without shift/unshift (but with the equivalent functionality). I'd like the extra performance to build a fast character FIFO with a String. Eric ------=_Part_15663_6296557.1159333680122 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline

On 9/26/06, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
Hi,

In message "Re: Array shift bug"
    on Mon, 25 Sep 2006 12:37:20 +0900, "Eric Mahurin" <eric.mahurin@gmail.com> writes:

|Here is a quick summary of what I did:

<snip>

I just submitted a patch based on yours to the HEAD.  Thank you!
It is fairly complex, so that I won't submit it to the stable (1.8).

|These same techniques (or something like them) could be applied to String
|also.

Since strings have no shift nor unshift, I am not going to add it to
the strings, until it is really needed.

Thank you again.  And I apologize that I left your patch ignored for a
full year.

                                                        matz.


Thanks matz,

I tried out the code and it looks better in a few spots, but it also got worse in a few (but not as common).  You can still use enormous amounts of memory because of the copy-on-write mechanism.  I am attaching a testbench for testing runtime and memory (sorry, linux only) performance for a bunch of array operations that can be O(1).  It also includes some new tests at the end (didn't have these before) that show O(n**2) memory when it should be O(n).  All of those performance (memory and runtime) issues were fixed in my patch.

Here are the results (for just 2^12=4096 iterations/elements):

+ : improved
- : needs work, still not to O(1)
* : partially improved, still not to O(1)
-- : worse

code                       2006-09-01    2006-09-26  eric's-patch
----                      -----------   -----------  ------------
                           sec     kB    sec     kB    sec     kB
                          ----   ----   ----   ----   ----   ----
;                         0.01    132   0.00      0   0.01    136
shift                     0.01    148   0.00    132   0.00    144
shift(1)                  0.01    152   0.13-   136   0.01    152
pop                       0.01    128   0.01    132   0.01    144
pop(1)                    0.01    152   0.00    136   0.01    152
shift;pop                 0.01    132   0.01    136   0.01    156
shift(1);pop(1)           0.01    136   0.14-   140   0.01    164
unshift(i)                0.13    132   0.01+   140   0.00    132
push(i)                   0.01    132   0.01      0   0.01    132
unshift(i);push(i)        0.14      0   0.00+   200   0.01    208
unshift(shift)            0.59   4816   0.00+     0   0.01    140
unshift(*shift(1))        0.60   4816   0.13*    68   0.01    148
push(pop)                 0.01    132   0.00      0   0.01    140
push(*pop(1))             0.38   4816   0.00+     8   0.01    148
push(shift)               0.45   4816   0.00+     0   0.01    140
push(*shift(1))           0.45   4816   0.14*     8   0.01    148
unshift(pop)              0.14    132   0.00+    60   0.01    140
unshift(*pop(1))          0.51   4816   0.01+    68   0.01    148
slice!(1)                 0.13    148   0.56--  132   0.00    144
delete_at(1)              0.14    148   0.55--  132   0.00    144
slice!(1,1)               0.58   8124   0.58-  8264   0.01    152
self[1,1]=[]              0.14    552   0.13-   536   0.01    548
slice!(-2)                0.00    148   0.00    132   0.00    144
delete_at(-2)             0.00    148   0.00    132   0.00    144
slice!(-2,1)              0.45   8120   0.46-  8260   0.01    148
self[-2,1]=[]             0.01    544   0.01    528   0.00    544
self[1,0]=[i]             0.16    140   0.14-     4   0.00    304
insert(1,i)               0.16    136   0.14-     0   0.00    304
self[-1,0]=[i]            0.02    136   0.01      4   0.01    308
insert(-2,i)              0.02    132   0.01      0   0.01    308
self[1,0]=slice!(1,1)     0.76   4056   0.77-  3956   0.01    144
insert(1,delete_at(1))    0.27    136   0.81--    4   0.01    144
self[-1,0]=slice!(-2,1)   0.56   4056   0.58   3956   0.02    144
insert(-2,delete_at(-2))  0.01    136   0.01      4   0.01    144
self[-1,0]=slice!(1,1)    0.73   4052   0.69-  3952   0.01    276
insert(-2,delete_at(1))   0.13    132   0.63--    0   0.01    276
self[1,0]=slice!(-2,1)    0.72   4052   0.74-  3952   0.01    212
insert(1,delete_at(-2))   0.17    132   0.17-     0   0.01    212
self[i]=self[i]           0.00    136   0.00      4   0.01    140
self[i]=at(i)             0.00    136   0.01      4   0.00    140
self[i,1]=self[i,1]       0.50   3960   0.50-  3952   0.01    144
self[-i-1]=self[-i-1]     0.01    140   0.01      8   0.02    144
self[-i-1]=at(-i-1)       0.02    140   0.01      8   0.01    144
self[-i-1,1]=self[-i-1,1] 0.49   4056   0.50-  3956   0.01    144
self[-i-1]=self[i]        0.01    132   0.01      0   0.01    136
self[-i-1]=at(i)          0.01    132   0.01      0   0.01    136
self[-i-1,1]=self[i,1]    0.57   4044   0.59-  3948   0.01    140
self[i]=self[-i-1]        0.01    136   0.01      4   0.01    140
self[i]=at(-i-1)          0.01    136   0.01      4   0.01    140
self[i,1]=self[-i-1,1]    0.56   4048   0.59-  3952   0.02    140
push(shift(1))            8.15 393900   0.24*     4   0.02    312
unshift(pop(1))           4.80 393920   0.01+    60   0.02    308
insert(-1,slice!(0,1))    6.05 262964  36.24- 262836  0.04    404
insert(0,slice!(-1,1))    2.71 262980  73.98- 262852  0.03    304
self[i]=self[i,1]         9.84 262924  18.77- 262832  0.02    268
self[-i-1]=self[-i-1,1]   8.36 262976  39.82- 262820  0.03    272
self[-i-1]=self[i,1]      5.94 262840  38.00- 262816  0.03    132
self[i]=self[-i-1,1]      0.90 262824  19.97- 262800  0.03    136


Notice how bad the memory and runtime is for these last ones.  And this is only for 4096 elements/iterations!

I think the rest of array.c should be overhauled just like I had to do in my original patch.

I still would like to see the same done for String sometime.  The same issues exist.  You'll find many deficiencies even without shift/unshift (but with the equivalent functionality).  I'd like the extra performance to build a fast character FIFO with a String.

Eric

------=_Part_15663_6296557.1159333680122-- ------=_Part_15662_16317407.1159333680122 Content-Type: text/plain; name=array_ends.rb.txt; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: base64 X-Attachment-Id: f_esl8c9ns Content-Disposition: attachment; filename="array_ends.rb.txt" CnJlcXVpcmUgJ2JlbmNobWFyaycKCiNpbml0IGZpbmFsIGNvZGUgZWxlbWVudC1hc3NlcnRpb24K Cgp0ZXN0cyA9ICV3ewoKMSAgIDEgICA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkK ICAgICAgICAKMS41IDAuNSBzaGlmdCAgICAgICAgICAgICAgICAgICAgICAgICAgIGkrbgoxLjUg MC41IHNoaWZ0KDEpICAgICAgICAgICAgICAgICAgICAgICAgaStuCjEuNSAwLjUgcG9wICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBpCjEuNSAwLjUgcG9wKDEpICAgICAgICAgICAgICAgICAg ICAgICAgICBpCjIgICAwICAgc2hpZnQ7cG9wICAgICAgICAgICAgICAgICAgICAgICBuaWwKMiAg IDAgICBzaGlmdCgxKTtwb3AoMSkgICAgICAgICAgICAgICAgIG5pbAogICAgICAgIAowLjUgMS41 IHVuc2hpZnQoaSkgICAgICAgICAgICAgICAgICAgICAgKGk+PW4pJiYoaS1uKXx8KG4tMS1pKQow LjUgMS41IHB1c2goaSkgICAgICAgICAgICAgICAgICAgICAgICAgKGk+PW4vMikmJihpLW4vMil8 fGkKMCAgIDIgICB1bnNoaWZ0KGkpO3B1c2goaSkgICAgICAgICAgICAgIChpPj1uKSYmKGktbil8 fChuLTEtaSkKICAgICAgICAKMSAgIDEgICB1bnNoaWZ0KHNoaWZ0KSAgICAgICAgICAgICAgICAg IGkKMSAgIDEgICB1bnNoaWZ0KCpzaGlmdCgxKSkgICAgICAgICAgICAgIGkKMSAgIDEgICBwdXNo KHBvcCkgICAgICAgICAgICAgICAgICAgICAgIGkKMSAgIDEgICBwdXNoKCpwb3AoMSkpICAgICAg ICAgICAgICAgICAgIGkKMSAgIDEgICBwdXNoKHNoaWZ0KSAgICAgICAgICAgICAgICAgICAgIGkK MSAgIDEgICBwdXNoKCpzaGlmdCgxKSkgICAgICAgICAgICAgICAgIGkKMSAgIDEgICB1bnNoaWZ0 KHBvcCkgICAgICAgICAgICAgICAgICAgIGkKMSAgIDEgICB1bnNoaWZ0KCpwb3AoMSkpICAgICAg ICAgICAgICAgIGkKICAgICAgICAKMS41IDAuNSBzbGljZSEoMSkgICAgICAgICAgICAgICAgICAg ICAgIChpPDEpJiZpfHwoaStuKQoxLjUgMC41IGRlbGV0ZV9hdCgxKSAgICAgICAgICAgICAgICAg ICAgKGk8MSkmJml8fChpK24pCjEuNSAwLjUgc2xpY2UhKDEsMSkgICAgICAgICAgICAgICAgICAg ICAoaTwxKSYmaXx8KGkrbikKMS41IDAuNSBzZWxmWzEsMV09W10gICAgICAgICAgICAgICAgICAg IChpPDEpJiZpfHwoaStuKQoxLjUgMC41IHNsaWNlISgtMikgICAgICAgICAgICAgICAgICAgICAg KGk+bi8yLTIpJiYoaStuKXx8aQoxLjUgMC41IGRlbGV0ZV9hdCgtMikgICAgICAgICAgICAgICAg ICAgKGk+bi8yLTIpJiYoaStuKXx8aQoxLjUgMC41IHNsaWNlISgtMiwxKSAgICAgICAgICAgICAg ICAgICAgKGk+bi8yLTIpJiYoaStuKXx8aQoxLjUgMC41IHNlbGZbLTIsMV09W10gICAgICAgICAg ICAgICAgICAgKGk+bi8yLTIpJiYoaStuKXx8aQogICAgICAgIAowLjUgMS41IHNlbGZbMSwwXT1b aV0gICAgICAgICAgICAgICAgICAgaj1uLWk7KGo8MCkmJihpLW4pfHwoaj49bikmJml8fGoKMC41 IDEuNSBpbnNlcnQoMSxpKSAgICAgICAgICAgICAgICAgICAgIGo9bi1pOyhqPDApJiYoaS1uKXx8 KGo+PW4pJiZpfHxqCjAuNSAxLjUgc2VsZlstMSwwXT1baV0gICAgICAgICAgICAgICAgICBqPWkt bi8yKzE7KGo8MCkmJml8fChqPj1uKSYmKGktbil8fGoKMC41IDEuNSBpbnNlcnQoLTIsaSkgICAg ICAgICAgICAgICAgICAgIGo9aS1uLzIrMTsoajwwKSYmaXx8KGo+PW4pJiYoaS1uKXx8agoKMSAg IDEgICBzZWxmWzEsMF09c2xpY2UhKDEsMSkgICAgICAgICAgIGkKMSAgIDEgICBpbnNlcnQoMSxk ZWxldGVfYXQoMSkpICAgICAgICAgIGkKMSAgIDEgICBzZWxmWy0xLDBdPXNsaWNlISgtMiwxKSAg ICAgICAgIGkKMSAgIDEgICBpbnNlcnQoLTIsZGVsZXRlX2F0KC0yKSkgICAgICAgIGkKCjEgICAx ICAgc2VsZlstMSwwXT1zbGljZSEoMSwxKSAgICAgICAgICAoKGk8MSl8fChpPj1uLTEpKSYmaXx8 KChpKzEpJShuLTIpKzEpCjEgICAxICAgaW5zZXJ0KC0yLGRlbGV0ZV9hdCgxKSkgICAgICAgICAo KGk8MSl8fChpPj1uLTEpKSYmaXx8KChpKzEpJShuLTIpKzEpCjEgICAxICAgc2VsZlsxLDBdPXNs aWNlISgtMiwxKSAgICAgICAgICAoKGk8MSl8fChpPj1uLTEpKSYmaXx8KChpLTMpJShuLTIpKzEp CjEgICAxICAgaW5zZXJ0KDEsZGVsZXRlX2F0KC0yKSkgICAgICAgICAoKGk8MSl8fChpPj1uLTEp KSYmaXx8KChpLTMpJShuLTIpKzEpCgoxICAgMSAgIHNlbGZbaV09c2VsZltpXSAgICAgICAgICAg ICAgICAgaQoxICAgMSAgIHNlbGZbaV09YXQoaSkgICAgICAgICAgICAgICAgICAgaQoxICAgMSAg IHNlbGZbaSwxXT1zZWxmW2ksMV0gICAgICAgICAgICAgaQoxICAgMSAgIHNlbGZbLWktMV09c2Vs ZlstaS0xXSAgICAgICAgICAgaQoxICAgMSAgIHNlbGZbLWktMV09YXQoLWktMSkgICAgICAgICAg ICAgaQoxICAgMSAgIHNlbGZbLWktMSwxXT1zZWxmWy1pLTEsMV0gICAgICAgaQoxICAgMSAgIHNl bGZbLWktMV09c2VsZltpXSAgICAgICAgICAgICAgKGk+PW4vMikmJihuLTEtaSl8fGkKMSAgIDEg ICBzZWxmWy1pLTFdPWF0KGkpICAgICAgICAgICAgICAgIChpPj1uLzIpJiYobi0xLWkpfHxpCjEg ICAxICAgc2VsZlstaS0xLDFdPXNlbGZbaSwxXSAgICAgICAgICAoaT49bi8yKSYmKG4tMS1pKXx8 aQoxICAgMSAgIHNlbGZbaV09c2VsZlstaS0xXSAgICAgICAgICAgICAgKGk+PW4vMikmJml8fChu LTEtaSkKMSAgIDEgICBzZWxmW2ldPWF0KC1pLTEpICAgICAgICAgICAgICAgIChpPj1uLzIpJiZp fHwobi0xLWkpCjEgICAxICAgc2VsZltpLDFdPXNlbGZbLWktMSwxXSAgICAgICAgICAoaT49bi8y KSYmaXx8KG4tMS1pKQoKMSAgIDEgICBwdXNoKHNoaWZ0KDEpKSAgICAgICAgICAgICAgICAgIFtp XQoxICAgMSAgIHVuc2hpZnQocG9wKDEpKSAgICAgICAgICAgICAgICAgW2ldCgoxICAgMSAgIGlu c2VydCgtMSxzbGljZSEoMCwxKSkgICAgICAgICAgW2ldCjEgICAxICAgaW5zZXJ0KDAsc2xpY2Uh KC0xLDEpKSAgICAgICAgICBbaV0KCjEgICAxICAgc2VsZltpXT1zZWxmW2ksMV0gICAgICAgICAg ICAgICBbaV0KMSAgIDEgICBzZWxmWy1pLTFdPXNlbGZbLWktMSwxXSAgICAgICAgIFtpXQoxICAg MSAgIHNlbGZbLWktMV09c2VsZltpLDFdICAgICAgICAgICAgKGk+PW4vMikmJltuLTEtaV18fFtb aV1dCjEgICAxICAgc2VsZltpXT1zZWxmWy1pLTEsMV0gICAgICAgICAgICAoaT49bi8yKSYmW1tp XV18fFtuLTEtaV0KCn0KCkZpZWxkcyA9IDQKCkFSR1ZbMF0gfHw9ICJydWJ5IgpBUkdWWzFdIHx8 PSAiMTIiCgplbnRyeSA9IDAgICAKd2hpbGUgZW50cnk8dGVzdHMuc2l6ZQogICAgaW5pdCxmaW5h bCxjb2RlLGFzc2VydCA9IHRlc3RzW2VudHJ5LEZpZWxkc10KICAgIGluaXQgPSBpbml0LnRvX2YK ICAgIGZpbmFsID0gZmluYWwudG9fZgogICAgaW5pdCtmaW5hbD09MiBvciByYWlzZShpbml0LnRv X3MrIisiK2ZpbmFsLnRvX3MrIiE9MiIpOwogICAgcHJpbnRmKCIlLTMycyIsY29kZSkKICAgIG4g PSBuaWwKICAgIHJ1YnkgPSBuaWwKICAgIEFSR1YuZWFjaCB7IHx4fAogICAgICAgIGlmIHgudG9f aS5ub256ZXJvPwogICAgICAgICAgICBuID0gMSA8PCB4LnRvX2kKICAgICAgICBlbHNlCiAgICAg ICAgICAgIHJ1YnkgPSB4CiAgICAgICAgZW5kCiAgICAgICAgbmV4dCB1bmxlc3MgbiAmJiBydWJ5 CiAgICAgICAgc3lzdGVtKHJ1YnksJy1lJywlUTwKICAgICAgICAgICAgbiA9ICN7bn0KICAgICAg ICAgICAgcmVzdWx0ID0gQXJyYXkubmV3KCN7KG4qZmluYWwpLnRvX2l9KSB7IHxpfCAje2Fzc2Vy dH0gfQogICAgICAgICAgICBHQy5zdGFydAogICAgICAgICAgICBtZW0wID0gbmlsCiAgICAgICAg ICAgIElPLnJlYWRsaW5lcygiL3Byb2MvXCN7UHJvY2Vzcy5waWR9L3N0YXR1cyIpLmdyZXAoL15W bVNpemU6XFxzKihcXGQrKVxccyprQiQvKSB7CiAgICAgICAgICAgICAgICBtZW0wID0gJDEudG9f aTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhID0gKDAuLi4jeyhuKmluaXQpLnRvX2l9KS50 b19hCiAgICAgICAgICAgIHRpbWUwID0gUHJvY2Vzcy50aW1lcwogICAgICAgICAgICB0aW1lMCA9 IHRpbWUwLnV0aW1lK3RpbWUwLnN0aW1lCiAgICAgICAgICAgIGJlZ2luCiAgICAgICAgICAgICAg ICBhLmluc3RhbmNlX2V2YWwgeyN7bn0udGltZXN7IHxpfAogICAgICAgICAgICAgICAgICAgICN7 Y29kZX0KICAgICAgICAgICAgICAgIH19CiAgICAgICAgICAgIHJlc2N1ZQogICAgICAgICAgICAg ICAgIyBpbiBjYXNlIHRoaXMgcnVieSBkb2Vzbid0IGhhbmRsZSB0aGlzIGNvZGUKICAgICAgICAg ICAgICAgIHByaW50ZigiICU2cyAlNnMiLCItIiwiLSIpCiAgICAgICAgICAgICAgICBleGl0CiAg ICAgICAgICAgIGVuZAogICAgICAgICAgICB0aW1lMSA9IFByb2Nlc3MudGltZXMKICAgICAgICAg ICAgdGltZTEgPSB0aW1lMS51dGltZSt0aW1lMS5zdGltZQogICAgICAgICAgICBtZW0xID0gbmls CiAgICAgICAgICAgIElPLnJlYWRsaW5lcygiL3Byb2MvXCN7UHJvY2Vzcy5waWR9L3N0YXR1cyIp LmdyZXAoL15WbVNpemU6XFxzKihcXGQrKVxccyprQiQvKSB7CiAgICAgICAgICAgICAgICBtZW0x ID0gJDEudG9faTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludGYoIiAlNi4yZiAlNmQi LHRpbWUxLXRpbWUwLG1lbTEtbWVtMCkKICAgICAgICAgICAgYT09cmVzdWx0IG9yIHJhaXNlKGEu aW5zcGVjdCsnIT0nK3Jlc3VsdC5pbnNwZWN0KQogICAgICAgID4pIG9yIHJhaXNlCiAgICB9CiAg ICBwdXRzCiAgICBlbnRyeSArPSBGaWVsZHMKZW5kCgoK ------=_Part_15662_16317407.1159333680122--