Skip to main content

News

Topic: Link.js v0.4.2 (Read 74311 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: [code] Link.js v0.2.3
Reply #60
tl;dr: Long rant gloat about how I "win", when really it's only for Chrome that I "win", but a good start nevertheless, and that I really do think Alpha has chance of blowing us all away.

Actually, I'm faster than a for loop sometimes. It technically shouldn't be possible, but I did a test and these two perform the same, and in fact the top one performs better on average (I think it knows 'noop' does nothing, and between Lazy and my library it may know that too):

Code: (javascript) [Select]

for (var i = 0; i < array.length; ++i) {
var result = add1(array[i]);
if (even(result)) noop(add1(result));
}


VS:
Code: (javascript) [Select]

for (var i = 0, l = array.length; i < l; ++i) {
var result = array[i] + 1;
if (result % 2 == 0) result += 1;
}


It seems counter-intuitive that the top one is faster since it must make calls, so this tells me that Chrome must be smart enough to inline functions anyways. which means Alpha's solution is happening for my code behind-the scenes anyways since my code most commonly resembles the first for loop.

So, therefore I might indeed have the absolute maximum in performance in my link library. I don't want to sound like a dick by saying that since I *know* Lazy tried hard and is far more flexible than my library. But if you want to see how one produces the fastest "querying library" this is it. This is the best... Otherwise you're just contending with raw for loop speed. If... if you can go faster than that, then you've succeeded in doing the impossible.

Closed the book, end of the road. Right here... For chrome. But, use Lazy if you want flexibility since this library has none of that. I can only see speed-critical, maximum performing code that consequently needs an upgrade to maintainability to ever use my library... And only there I can see a future for it. Sounds a lot like gaming, too. ;)

Of course, that is if you use Chrome. In FF and IE the experience is, fatser, but not as. And probably more noticeable in Sphere (might even be slower). It's one crutch is function calls. That's all... and Chome happens to have a good, fast solution for that, which my library leverages by incident.

So I digress, it might be possible to create a library good on all browsers, and in that case Alpha may have the right idea of generating the code for a for loop... Provided the construction itself is fast, and the generated code turns on any optimizations which I think doesn't. And is accepted in immature environments like IE. But it is really a promising lead in the best performance for such libraries.

Alpha: you've been quiet, I'm hoping you made some headway. And although I said yours sounds like cheating, well, technically I am. I'm interested in how your library performs outside of Chrome. :)
  • Last Edit: January 19, 2014, 02:51:12 am by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: [code] Link.js v0.2.4
Reply #61
Can Link work with multi-dimensional arrays?  I have a few for loops that look like this one in my battle engine:

Code: (javascript) [Select]
for (var iList = 0; iList < unitLists.length; ++iList) {
    for (var i = 0; i < unitLists[iList].length; ++i) {
        var unit = unitLists[iList][i];
        unit.beginCycle();
    }
}


...which isn't too bad as-is, but it gets a little hairy when the cycle actually gets underway further down.  I'm wondering if there's any way to express such a loop with Link, or if I have to do some remodeling first.
miniSphere 5.3.0 - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: [code] Link.js v0.2.4
Reply #62
Presently there is no such thing to search and filter 2D arrays, but you do bring up a good use case and I'll definitely start looking into it. That said since there is nothing to filter, I doubt Link would make the code any faster since filtering things is kind of it's strong suit.

Now onto the good stuff. Starting from Link 2.0 you can run multiple Link contexts, even inside each other, like so:
Code: (javascript) [Select]

Link(unitLists).each(function(item) { Link(item).invoke("beginCycle"); });


What's better is if you have any more 2D list processing you might get better results doing it the above mentioned way.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: [code] Link.js v0.2.4
Reply #63
I'm going to have to give that try.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: [code] Link.js v0.2.4
Reply #64
Ok, new feature Expand.

Code: (javascript) [Select]

var a = [[0, 1], [2, 3], [4, 5, 7], [6, 7]];
var s = Link(a).expand().filter(even).toArray(); // s = [0, 2, 4, 6]


I am still testing out the feature, but I think it's good to go. But some words of warning: .expand() treats the resultant list like a single dimension array. So, things like indexOf and toArray() will only give you the single array representation of their values in the end. It does this by design. I'll have to take a deeper look into how indexOf can return the index of a 2D element. But expect things like .each() and .invoke() to do exactly what you want them to do. :)
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: [code] Link.js v0.2.5b
Reply #65
Does it work with arrays of objects as well?

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: [code] Link.js v0.2.5b
Reply #66

Does it work with arrays of objects as well?


Not really. Why, is there a particular thing you want done with an array of objects that must use the object itself as an 'array-like' basket? I've been meaning to add more features for arrays of objects to it, but currently it's for arrays of arrays. It depends on what you want done, really.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: [code] Link.js v0.2.5b
Reply #67
I actually meant 2D arrays of objects.

But now that you mention it, a nifty feature that I would certainly use if it was available would be to specify certain properties of objects as a target array. Like so:

Code: [Select]

function StrangeObject(x, y, l){
  this.x = x;
  this.y = y;
  this.l = l; //an array.
}

var a1 = [3, 4, 3];
var a2 = [59];
var a3 = [2, 4, 0, 1];

var arr = [new StrangeObject(0, 0, a1), new StrangeObject(0, 1, a2), new StrangeObject(1, 0, a3)];

var s = Link(arr).expandNamedProperties(function(a){return a.l;}).filter(even).toArray(); // s = [4, 2, 4, 0]



I have had uses for something like this in the past, usually when storing relationships between objects. For instance, a list of entities that were within a certain range of each other.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: [code] Link.js v0.2.5b
Reply #68

I actually meant 2D arrays of objects.


Oh, yeah, Link can do 2D arrays of objects with .expand(), no problem. Now, this use case:


Code: [Select]

var arr = [new StrangeObject(0, 0, a1), new StrangeObject(0, 1, a2), new StrangeObject(1, 0, a3)];
var s = Link(arr).expandNamedProperties(function(a){return a.l;}).filter(even).toArray(); // s = [4, 2, 4, 0]


I have had uses for something like this in the past, usually when storing relationships between objects. For instance, a list of entities that were within a certain range of each other.


Is interesting. I could add an argument to expand, like so:
Code: (javascript) [Select]

var arr = [new StrangeObject(0, 0, a1), new StrangeObject(0, 1, a2), new StrangeObject(1, 0, a3)];
var s = Link(arr).expand("l").filter(even).toArray(); // s = [4, 2, 4, 0]


I think it won't be too bad. Without the prop name it'll expand a default array. I think this would be the most efficient.

Edit:

And so it is done, and now on the bleeding edge at GitHub. Keep coming with the ideas!!

Code: (javascript) [Select]

var a = [{a: [0, 1]}, {a: [2]}, {a: [3, 4, 5]}, {a: [6, 7]}];
var s = Link(a).expand("a").filter(even).toArray(); // s = [0, 2, 4, 6];


It occurred to me that you could emulate the above anyways with pluck and expand:
Code: (javascript) [Select]

var a = [{a: [0, 1]}, {a: [2]}, {a: [3, 4, 5]}, {a: [6, 7]}];
var s = Link(a).pluck("a").expand().filter(even).toArray(); // s = [0, 2, 4, 6];


I just added pluck, right now. :P
  • Last Edit: January 27, 2014, 03:54:17 am by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: [code] Link.js v0.2.5b
Reply #69
What does pluck do, exactly?  Really thinking this thing needs some proper documentation.  The readme helps, but it's a bit lacking in its description of a lot of query operations.  For example, is there any difference between first() and take()?  They both look like they do the same thing.  Same for filter() and where().

And regarding my question above and the response: I'm aware Link won't make this particular use case any faster. However, the turn resolver in Specs isn't all that complicated to begin with so I'll gladly accept a bit of overhead in favor of improved readability and, more importantly to me, scalability. I don't have to filter anything now, but I can see myself having to do so later on (prioritizing certain battlers, etc.).  Besides, I'm a hands-on kind of guy so this will give me practice using Link in a real-world scenario.
miniSphere 5.3.0 - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: [code] Link.js v0.2.5b
Reply #70
Yeah, making a proper API page is on my todo list. Also, .expand() should be quite fast in fact since it clears up some overhead.

Pluck does this:
Code: (javascript) [Select]

var a = [{ prop: "hi" }, { prop: "cool" }, { prop: "stuff" }];
var s = Link(a).pluck("prop").toArray();
print(s); // s = ["hi", "cool", "stuff"];


Pluck will use the named property throughout the rest of the expression. Without pluck the resulting array would have just been the objects.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: [code] Link.js v0.2.5b
Reply #71
Just have to say, this thing is awesome.  My six-line for loop above turned into this:
Code: (javascript) [Select]
Link(unitLists).expand().invoke('beginCycle');


I'm loving it already!  In theory Expand can be chained as well for 3+ dimensional arrays, right?
miniSphere 5.3.0 - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: [code] Link.js v0.2.5b
Reply #72

Just have to say, this thing is awesome.  My six-line for loop above turned into this:
Code: (javascript) [Select]
Link(unitLists).expand().invoke('beginCycle');


I'm loving it already!  In theory Expand can be chained as well for 3+ dimensional arrays, right?


Umm, yes, of course! :)
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: [code] Link.js v0.2.5b
Reply #73
Now the true test will be when I start doing some actual queries. :)
miniSphere 5.3.0 - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • miniSphere Developer
Re: [code] Link.js v0.2.5b
Reply #74
Not a feature request, but I vote to rename/alias expand() to unroll().  "Unroll" makes it clearer what it's actually doing, especially when the results are treated as a one-dimensional array thereafter (i.e. flattening, or "unrolling" the original 2D array).  "Expand" suggests only that you're widening the scope of the search, which while technically true, doesn't paint the whole picture.  So yeah, Expand should be called Unroll. 8)

Oh, and while I'm here, I might as well ask.  How much of a performance hit am I taking by doing the following?
Code: (javascript) [Select]
var isUnitAlive = function(it) { return it.isAlive(); };
this.playerUnits = Link(this.playerUnits).where(isUnitAlive).toArray();
this.enemyUnits = Link(this.enemyUnits).where(isUnitAlive).toArray();


I do that at the end of a CTB cycle to remove dead battlers from the fight.  Originally, I was running a for loop through the unit lists and removing dead battlers in-place using splice().  Here, I'm recreating the whole array with a query.  I know that must be a lot more expensive, I'm just wondering by how much.
miniSphere 5.3.0 - Cell compiler - SSj debugger
forum thread | on GitHub