Skip to content

Commit

Permalink
extract magic constant, add [0,len] special case
Browse files Browse the repository at this point in the history
  • Loading branch information
dcousens committed Aug 15, 2015
1 parent fd60fb3 commit c681bda
Showing 1 changed file with 17 additions and 16 deletions.
33 changes: 17 additions & 16 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -622,16 +622,6 @@ function base64Slice (buf, start, end) {
}
}

function decodeCodePointsArray (buf) {
var len = buf.length

if (len <= 0x10000) {
return String.fromCharCode.apply(String, buf) // avoid extra slice()
}

return binarySlice(buf, 0, len)
}

function utf8Slice (buf, start, end) {
end = Math.min(buf.length, end)
var res = []
Expand Down Expand Up @@ -700,7 +690,7 @@ function utf8Slice (buf, start, end) {
i += bytesPerSequence
}

return decodeCodePointsArray(res)
return binarySlice(res, 0, res.length)
}

function asciiSlice (buf, start, end) {
Expand All @@ -713,17 +703,28 @@ function asciiSlice (buf, start, end) {
return ret
}

// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
var MAX_ARGUMENTS_LENGTH = 0x10000

function binarySlice (buf, start, end) {
var chunk = 0x10000
var len = buf.length
end = Math.min(len, end)

// TODO: verify, this is probably the average case
if (start === 0 && end === len && end <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, buf)
}

This comment has been minimized.

Copy link
@dcousens

dcousens Aug 15, 2015

Author Collaborator

In terms of performance, I feel like we'll be able to squeeze more out of utf8slice before its worth really breaking out these conditionals.


var res = ''

// Decode in chunks to avoid "call stack size exceeded".
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
for (var i = start; i < end; i += chunk) {
var chunkEnd = Math.min(end, i + chunk)
for (var i = start; i < end; i += MAX_ARGUMENTS_LENGTH) {
var chunkEnd = Math.min(i + MAX_ARGUMENTS_LENGTH, end)

res += String.fromCharCode.apply(String, buf.slice(i, chunkEnd))
}

return res
}

Expand Down

4 comments on commit c681bda

@dcousens
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nolanlawson could you verify this is as performant as your last case? I'm seeing no difference here, with a considerable increase for the average case in binarySlice.

@nolanlawson
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.6s, a tiny bit slower (1.4 before), but still good in my opinion! 👍

@nolanlawson
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also if you're curious to test yourself, it's just:

hub clone pouchdb/pouchdb && cd pouchdb
npm i && npm run build && npm run dev
# open localhost:8000/tests/integration/?adapters=localstorage&grep=attach in a browser

@dcousens
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nolanlawson 14% difference isn't great, if consistent.
However, I'm working on some utf8slice improvements, so hopefully I'll cut it down even further.

Please sign in to comment.