Return-Path: X-Original-To: apmail-cordova-dev-archive@www.apache.org Delivered-To: apmail-cordova-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 02712EC4B for ; Tue, 15 Jan 2013 15:28:40 +0000 (UTC) Received: (qmail 27437 invoked by uid 500); 15 Jan 2013 15:28:39 -0000 Delivered-To: apmail-cordova-dev-archive@cordova.apache.org Received: (qmail 27140 invoked by uid 500); 15 Jan 2013 15:28:38 -0000 Mailing-List: contact dev-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cordova.apache.org Delivered-To: mailing list dev@cordova.apache.org Received: (qmail 27104 invoked by uid 99); 15 Jan 2013 15:28:37 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 15 Jan 2013 15:28:37 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of mmocny@google.com designates 209.85.220.49 as permitted sender) Received: from [209.85.220.49] (HELO mail-pa0-f49.google.com) (209.85.220.49) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 15 Jan 2013 15:28:31 +0000 Received: by mail-pa0-f49.google.com with SMTP id bi1so165162pad.8 for ; Tue, 15 Jan 2013 07:28:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:content-type; bh=+aAG5x2Q+counVdsYu4mlZ1zFG1EJV5kLBNrtzDgHzE=; b=Ao9T3KPdYvtsC2ScSFpXeI7BA8OqVmSXlk97J86yjMIkoQ85yHY1CLEke/5GDrysPX fp7Z2c7pmV2CClZjtbBDrcuZ+KwxLl4iapDvtIClEDx3j47hcDK9QqNPeeFIXn90w+y+ aL5hDZLRWmd+w9XnEH59fQK1eNGAAQpo+PriFzLw3iuFRPu8D3cJT0KTjUQGDRy/9B1p tVFUM7qT/C3PsJtnQwvvCR7ibItYlqfhbBCW5STwSc4kjYRtz6P3aictFC+AnlkTq7R1 S4vLRblTMyqbN4sKTs4osGGVc7ebIzWTN+EFergMa62PE0YQE9296uY80lB7dN12wMnX bc+w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:content-type; bh=+aAG5x2Q+counVdsYu4mlZ1zFG1EJV5kLBNrtzDgHzE=; b=CeXoS8goJbd//7aezf79vxPmN28YseWeQAF5lisE7e6HneLb/uLe9WBwB0Zj37SwX7 0eptRpheN4eAI9U+55BgXrD/cIjpnRZEz9z3oxXwueSWYd+PXbieKmzGTo8idxaKOLqh l5JrPLfS9pGROA+7Q99gr6fSZd6FZt8XFocdI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:content-type :x-gm-message-state; bh=+aAG5x2Q+counVdsYu4mlZ1zFG1EJV5kLBNrtzDgHzE=; b=FSO0L5Ipz40LG7Mtr0IYyOwqDJUJCCbkKhmCMDW2BU34qi4q9ZhbdvTJkbIJrFQqMf C6AL97rt06eIK97MSodTA0JRgGQNV67m62bOCOuzpNmnw6upxM2U5EFm1ZnktfUKJpzd 9uCvln657RytWXtVY8owfrt7y4rPQi2ktNIoM/hr8A/tX8BZfX4W0i4tRcBW8uMlJycj +XXbke80k0iw2fCtVrnYOGHNw2s2AfXTqvW1dSu0VOqubfHixnijxz0dNeGZd78zX9AL R1em44Tp9sSX4PPg9EhDFR5L1LCBJ/GFhKVUX3Gadme4eBU03pXgOhlnxAduKgILS6By uKUw== MIME-Version: 1.0 Received: by 10.68.132.232 with SMTP id ox8mr265478085pbb.46.1358263689687; Tue, 15 Jan 2013 07:28:09 -0800 (PST) Sender: mmocny@google.com Received: by 10.68.195.10 with HTTP; Tue, 15 Jan 2013 07:28:09 -0800 (PST) In-Reply-To: References: Date: Tue, 15 Jan 2013 10:28:09 -0500 X-Google-Sender-Auth: Hz6IR4nM01p54cxj1dMcT9q2sLU Message-ID: Subject: Re: Binary data across exec bridge From: Michal Mocny To: dev@cordova.apache.org Content-Type: multipart/alternative; boundary=047d7b10cbcbbc308904d3556884 X-Gm-Message-State: ALoCoQniOASd8d34RCamEiwKK6+SMffqqe4/bIlgmahob5YYT9QRwNOgBN/aAX0XxSgkiOinhAPlvJPL8TX7ElvBL+VAoRLyZLgHOOBnUlNk/12ycEC6ceba0b+b9OSe3FwZKEP10JnMqasbpLc+hpqVE6aGdWP8cb7mF81v+9P6ssv72UEQbc5boDuTjnt4P2QHHQO0GeCA X-Virus-Checked: Checked by ClamAV on apache.org --047d7b10cbcbbc308904d3556884 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Don, I had previously tried a byte array and found it quite a bit less efficient. I'll add that implementation and benchmark it officially. I did benchmarks on iphone5 today for two initial implementations: (1) Using base64 encoded javascript strings (2) Using non base64 encoded, unicode javascript strings (1) YES BASE64 ENCODE 2013-01-15 10:16:02.233 MobileSpecTest[1930:907] Multi-tasking -> Device: YES, App: YES 2013-01-15 10:16:02.749 MobileSpecTest[1930:907] [LOG] Device =3D iOS 6.0.2 2013-01-15 10:16:38.104 MobileSpecTest[1930:907] [LOG] Started exec benchmark with payload length: 1 2013-01-15 10:16:39.103 MobileSpecTest[1930:907] [LOG] Calls per second: 274.72527472527474 2013-01-15 10:16:55.995 MobileSpecTest[1930:907] [LOG] Started exec benchmark with payload length: 32000 2013-01-15 10:17:01.007 MobileSpecTest[1930:907] [LOG] Calls per second: 18.909235668789808 2013-01-15 10:17:02.795 MobileSpecTest[1930:907] [LOG] Started exec benchmark with payload length: 32000 2013-01-15 10:17:07.785 MobileSpecTest[1930:907] [LOG] Calls per second: 18.59628074385123 2013-01-15 10:17:14.402 MobileSpecTest[1930:907] [LOG] Started exec benchmark with payload length: 32 2013-01-15 10:17:19.402 MobileSpecTest[1930:907] [LOG] Calls per second: 265.89364254298283 2013-01-15 10:17:20.651 MobileSpecTest[1930:907] [LOG] Started exec benchmark with payload length: 32 2013-01-15 10:17:25.651 MobileSpecTest[1930:907] [LOG] Calls per second: 263.69452219112355 2013-01-15 10:17:36.187 MobileSpecTest[1930:907] [LOG] Started exec benchmark with payload length: 1024 2013-01-15 10:17:41.189 MobileSpecTest[1930:907] [LOG] Calls per second: 185.8141858141858 2013-01-15 10:17:44.701 MobileSpecTest[1930:907] [LOG] Started exec benchmark with payload length: 1024 2013-01-15 10:17:49.699 MobileSpecTest[1930:907] [LOG] Calls per second: 186.9626074785043 2013-01-15 10:17:51.084 MobileSpecTest[1930:907] [LOG] Started exec benchmark with payload length: 1024 2013-01-15 10:17:56.082 MobileSpecTest[1930:907] [LOG] Calls per second: 184.8 (2) NO BASE64 ENCODE 2013-01-15 10:12:12.387 MobileSpecTest[1905:907] Multi-tasking -> Device: YES, App: YES 2013-01-15 10:12:12.892 MobileSpecTest[1905:907] [LOG] Device =3D iOS 6.0.2 2013-01-15 10:12:21.462 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 1 2013-01-15 10:12:22.458 MobileSpecTest[1905:907] [LOG] Calls per second: 26= 7 2013-01-15 10:12:32.212 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 32000 2013-01-15 10:12:37.204 MobileSpecTest[1905:907] [LOG] Calls per second: 15.18784972022382 2013-01-15 10:12:38.898 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 32000 2013-01-15 10:12:43.897 MobileSpecTest[1905:907] [LOG] Calls per second: 15.163607342378292 2013-01-15 10:12:51.802 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 32 2013-01-15 10:12:56.801 MobileSpecTest[1905:907] [LOG] Calls per second: 261.8952419032387 2013-01-15 10:12:58.534 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 32 2013-01-15 10:13:03.533 MobileSpecTest[1905:907] [LOG] Calls per second: 262.89484206317474 2013-01-15 10:14:19.153 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 1 2013-01-15 10:14:24.154 MobileSpecTest[1905:907] [LOG] Calls per second: 269.43833699780134 2013-01-15 10:14:27.605 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 1 2013-01-15 10:14:32.604 MobileSpecTest[1905:907] [LOG] Calls per second: 272.34553089382126 2013-01-15 10:14:42.134 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 1024 2013-01-15 10:14:47.132 MobileSpecTest[1905:907] [LOG] Calls per second: 173.6 2013-01-15 10:14:49.217 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 1024 2013-01-15 10:14:54.216 MobileSpecTest[1905:907] [LOG] Calls per second: 173.8 2013-01-15 10:14:55.518 MobileSpecTest[1905:907] [LOG] Started exec benchmark with payload length: 1024 2013-01-15 10:15:00.520 MobileSpecTest[1905:907] [LOG] Calls per second: 173.22677322677322 A note about the data: I was using bytes from 0..255 evenly distributed, and the JSON serialization of that looks like: "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u00= 0e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\= u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=3D>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefg= hijklmnopqrstuvwxyz{|}~=7F=80=81=82=83=84 =86=87=88=89=8A=8B=8C=8D=8E=8F=90=91=92=93=94=95=96=97=98=99=9A=9B=9C=9D=9E= =9F =A1=A2=A3=A4=A5=A6=A7=A8=A9=AA=AB=AC=AD=AE=AF=B0=B1=B2=B3=B4=B5=B6=B7=B8=B9= =BA=BB=BC=BD=BE=BF=C0=C1=C2=C3=C4=C5=C6=C7=C8=C9=CA=CB=CC=CD=CE=CF=D0=D1=D2= =D3=D4=D5=D6=D7=D8=D9=DA=DB=DC=DD=DE=DF=E0=E1=E2=E3=E4=E5=E6=E7=E8=E9=EA=EB= =EC=ED=EE=EF=F0=F1=F2=F3=F4=F5=F6=F7=F8=F9=FA=FB=FC=FD=FE=FF" Which is a 400 character length string. Base64 encoding 256 characters is a 342 character string. However, if the data were not evenly distributed, and instead consisted mostly of readable characters (as is the case with many protocols) then non-base64 encoded would be faster. I've left the base64 encoded version, assuming binary data will be random, and also because we already support sending raw strings across the bridge, so a plugin developer can do that if its more efficient. Either way, this is terribly slow, and I'll have to start getting creative. Finally, there is a bug where it seems that data larger than ~64k wont transfer across the bridge at all. Andrew, is there a known limit to how much payload exec can send across? -Michal On Wed, Jan 9, 2013 at 3:57 PM, Don Coleman wrote: > For the phonegap-nfc plugin I send binary data between native and > javascript as a byte array in JSON. > > static JSONArray byteArrayToJSON(byte[] bytes) { > JSONArray json =3D new JSONArray(); > for (int i =3D 0; i < bytes.length; i++) { > json.put(bytes[i]); > } > return json; > } > > > On Wed, Jan 9, 2013 at 3:00 PM, Andrew Grieve > wrote: > > > > On Wed, Jan 9, 2013 at 10:15 AM, Michal Mocny > wrote: > > > > > On Tue, Jan 8, 2013 at 10:22 PM, Andrew Grieve > > > wrote: > > > > > > > Rather than "binary data", I think we should focus strictly on > > > > "ArrayBuffer". I think the only other binary data concept is Blob, > and > > > Blob > > > > is easy to create from an ArrayBuffer. > > > > > > > > As for how to have one of these show up in a JSON object, I think i= t > will > > > > be tough to make this work. Most platforms assume that you can past= e > the > > > > JSON into an eval / JSON.parse, and it will come out correctly. Tha= t > > > can't > > > > be the case for ArrayBuffers. Maybe we should just not support this= . > The > > > > use-case here is being able to pass multiple values to callbacks. F= or > > > > ArrayBuffers, maybe we can passing the usual payload plus an option= al > > > > ArrayBuffer as an additional parameter. I don't think it would be > > > necessary > > > > to have multiple ArrayBuffers for a single callback... > > > > > > > > > > To understand correct, does this mean that you propose a single > ArrayBuffer > > > instead of an arguments list, or, to add a 6th parameter to exec whic= h > is > > > the one and only ArrayBuffer? > > > > > > I propose yet another option, maybe you can any number of ArrayBuffer= s > in > > > the arguments list, but not embedded in any subobject. Thus, > semantically > > > the arguments array stops being JSON serializable, and the individual > > > arguments are either ArrayBuffers or json-serializable (this also > leaves > > > door open to add more types in the future). > > > > > > > Hmm, I wasn't even thinking about the JS->native case actually. I was > only > > thinking about native->JS. > > What you propose sounds good for JS->Native. > > > > > > > > > > > > > > > > > > > > > > My ideas for transferring this over the bridge on iOS include: > > > > > > - an array of numbers > > > > - a string of shorts encoded as chars with unicode chars encoded as > > > \uXXXX > > > > - a URL that the client can fetch via XHR and we can return the > binary > > > data > > > > via CDVURLProtocol (advantage here is that XHR2 can request the > payload > > > as > > > > an ArrayBuffer instead of having to construct the ArrayBuffer > > > > after-the-fact > > > > > > > interesting idea! > > > > > > > > > > > > > > For Android, the string of short-encoded chars is probably the best > bet > > > > since the bridge natively supports transferring strings without > having to > > > > parse them as JS literals. > > > > > > > > > > > > > > > > On Tue, Jan 8, 2013 at 4:05 PM, Michal Mocny > wrote: > > > > > > > > > Created https://issues.apache.org/jira/browse/CB-2173 > > > > > > > > > > > > > > > On Tue, Jan 8, 2013 at 3:52 PM, Michal Mocny > > > wrote: > > > > > > > > > > > Background: I've been working on implementing chrome.socket [1] > for > > > > > mobile > > > > > > chrome apps [2] and porting circ (an irc chrome app) [3]. Teas= er > > > > video: > > > > > > https://docs.google.com/open?id=3D0B0UdPHoQPXheTzhTZXZHUlpGWHM = (this > > > is > > > > > > still in its infancy, and I certainly do plan to submit a > version of > > > > the > > > > > > socket api that will work in cordova without any mobile chrome > app > > > > > magic). > > > > > > > > > > > > As part of doing that, I had to implement sending binary data > across > > > > the > > > > > > exec bridge (on ios for now), and I think it may be a good idea > to > > > just > > > > > add > > > > > > that functionality to cordova core. My current implementation = is > > > > > certainly > > > > > > not the best, so I will extend the exec bridge echo benchmarks = to > > > test > > > > > > binary transfer speeds and we can improve over time. > > > > > > > > > > > > My first step would be to implement helpers in js/ios/android > which > > > > > plugin > > > > > > devs can call manually to serialize/deserialize binary data > into/from > > > > > > whatever magical form is most efficient. > > > > > > > > > > > > Next, I would try to automate these helpers from within the exe= c > call > > > > > > (e.g. iterate arguments looking for ArrayBuffer/Blob/etc types > before > > > > > json > > > > > > serialization). As part of doing this, I would need to add > "hints" > > > > about > > > > > > the underlying argument types/some clever way to encode semanti= c > > > > > > information about the arguments list, which we currently do not > do. > > > > > > > > > > > > If anyone has any suggestions or objections please let me know! > > > > > > > > > > > > -Michal > > > > > > > > > > > > [1] http://developer.chrome.com/apps/socket.html > > > > > > [2] > > > > > > > > > > > > > > > > > > > https://github.com/MobileChromeApps/chrome-cordova/blob/master/api/chrome= /socket.jsand > > > > > > > > > https://github.com/MobileChromeApps/chrome-cordova/tree/master/plugin= s > > > > > > [3] https://github.com/flackr/circ > > > > > > > > > > > > > > > > > > > --047d7b10cbcbbc308904d3556884--