Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Great question!

     v:("select";,"*";"from";"tacos")

     us:{$[#i:&{(y~*K)&"*"~*x}':x;@[x;i;:[;,"_"]];x]}              
     \t:100000 us v
    233
     us:{$[(*K;,"*")~(y;x);,"_";x]}':
     \t:100000 us v
    206
     w:(*K;,"*");us:{$[w~(y;x);,"_";x]}':
     \t:100000 us v
    179
     us:{$[x~(z;y);,"_";y]}[(*K;,"*")]':
     \t:100000 us v
    129
I think it's important to remember just how simple k is: We the programmer know that (*K;,"*") isn't supposed to change, so we should be explicit so k "knows" this as well. In addition to never changing, we also know the value is only used once, so we really don't want to look anything up in the workspace every time we call us: Again, let us be explicit.

On the other hand, this:

     us:{$[#i:& XXX ;@[x;i;:[; YYY ]];x]}
is an extremely recognisable idiom. It occurs several times in sql.k so the reader is probably used to seeing it at this point. It also has a similar syntactic structure to the APL '@' so it may be more "obvious" to an APL programmer. Maybe the reason I write it this way is that I'm not a very experienced APL programmer :)


Thank you for the extensive answer, that's very interesting that there's such a performance difference. I would have naively assumed if anything keeping it as a constant would be faster.

Another question: Why do

  $[#i:& XXX ; @[x;i;:[; YYY]]; x]
when (if I'm not mistaken, which I could be) you can do

  @[x;i:& XXX;:[; YYY]]
Performance again? A quick test using ngn/k did seem to find the first one faster, but only marginally.


That's a harder question. Why do other people do the things they do? One reason might be because it was convenient for them to write (and debug) things that way.

But it is possible they are doing it for performance reasons, so maybe it's worth considering why it should be faster? That is to say, should the programmer assume the latter is faster than the former?

To do that, I would suggest putting yourself in the shoes of the implementor: You have a choice of how it should be implemented. Knowing this decision will affect every use of @[x;i;f], should it begin with an if statement like this?

    if(y->n == 0)return x;
But before you answer, remember the next thing @[x;i;f] needs to do, is consider if x has any additional references, because if it does, it has make a copy of x. That means there already needs to be an if statement that looks like this:

    if(x->r > 0) x = copy(x);
So one way to think about this, is to ask if you are implementing @[x;i;f], should you choose one branch or two?

    $[#i:& XXX ; @[x;i;:[; YYY]]; x]
Also: Do you see the part that goes :[;YYY]? That's constructing an object. Do you think it is worth avoiding that allocation if possible?


Ok, that all makes sense, thank you.

And thanks for pointing out the pattern in the first place, it makes sense now how you were able to parse the original expression so quickly.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: