Indexing blobs vs strings

This is a question for @peter - or someone else with deep knowledge of the inner workings of Squirrel :))

I’ve been writing some low level code where I need to iterate through a couple blobs and do some bit math on them, and I need it to be as efficient as possible. I noticed that it takes significantly less time to convert a blob to a string, and iterate through the string’s characters than it does to simply iterate through the string:

`server.log(“Starting…”);

_millis <- hardware.millis.bindenv(hardware);

local b1 = blob(12888)
local b2 = blob(12888)

local start, end;

for(local i = 0; i < 12888; i++) {
b1.writen(0xFF, ‘b’);
b2.writen(math.rand() & 0xFF, ‘b’)
}

//-------------------- TEST 1: Indexing Blobs --------------------//
// ~447ms (imp001)
b1.seek(0);
b2.seek(0);

start = _millis();

for(local i = 0; i < 12888; i++) {
if ((b1[i] & b2[i]) != b2[i]) server.log(“bad”);
}

end = _millis();

server.log("Test 1 (indexing blobs): " + (end - start) + “ms”);

//-------------------- TEST 2: indexing tostring’ed blobs --------------------//
// ~173ms (imp001)
b1.seek(0);
b2.seek(0);

start = _millis();

local s1 = b1.tostring();
local s2 = b2.tostring();

for(local i = 0; i < 12888; i++) {
if ((s1[i] & s2[i]) != s2[i]) server.log(“bad”);
}

end = _millis();

server.log("Test 2 (indexing .tostring’ed blobs): " + (end - start) + “ms”);`

Converting the blob to a string takes about 3ms (which is not surprising since that’s probably a pretty low level memcopy or something)…

So I’m curious about why indexing into a blob takes SO much longer than indexing into a string… any insights?

Can blobs be non-contiguous, perhaps? Maybe the extra time relates to an extra step to map the index to the correct memory offset. Regardless, this is useful information to know. I’d assumed performance would have been similar or the other way around.

That’s really interesting…

I kind of assumed blobs were a built in type, but looking at the Squirrel docs they show up under the stdlib docs not the core Squirrel docs!

Oh, interesting. Blobs can’t be non-contiguous (that would be a neat feature), but what’s actually happening is that “string” is a built-in type, so the internal function dispatch for the indexing operation is simple and fast. For “blob”, though, there’s some more indirection involved before it works out the actual type, so it takes a bit longer.

Peter

In upstream Squirrel, typeof(blob) is “instance”, because they’re instances of a pre-defined class. (In a rare but hopefully minor incompatibility with upstream, on agents and imps typeof(blob) is “meta”, which is also the type of our other native pseudo-instances such as the “imp” and “hardware” objects.)

Peter