Processing.js sleep - javascript

I want to write a sleep() function in javascript/processing.js. I.e: a function that interrupts the flow of the program for however many seconds.
It is obvious how to do this with "busy waiting", but this tends to slow down the browser and make things unusable
I know "sleep" is not good javascript. I want this function for didactic purposes (help kids understand their code), not for production use.
Since it is meant do be didactic, an explicit callback is too much of a complication. Calling the function should be as simple as in , say, bash or php -- however, we can use the most arcane things, just as long as they remain hidden inside the sleep function (including processing.js tricks)
I am aware of question What is the JavaScript version of sleep()?, but still hope there is a hack to stop processing.js (or perhaps a real javascript solution, however ill-advised it might be)
This function should work outside a draw() loop -- if it works inside as well, that is a bonus
If it is relevant, this function is meant to be used on Khan Academy

It is obvious how to do this with "busy waiting", but this tends to slow down the browser and make things unusable
A sleep() function would also cause this behavior, since JavaScript is single-threaded.
Since it is meant do be didactic, an explicit callback is too much of a complication.
You've pretty much answered your own question: there is no way to do a sleep() function in JavaScript without using a callback or busy waiting.
You might consider using Java mode to show sleep(), but it sounds like busy waiting is the way to go.
And in my humble opinion, even if you could find a hack to cause a sleep, that's probably not a great example for kids, since their code would never do that. They're much more likely to try to render too many objects. If you're trying to demonstrate that doing too much inside of the draw() function will be bad, then why not just have them do too much inside the draw() function? Teach them about for loops and then ask them to see what happens when they draw 100 rectangles, or 1000, or 1,000,000!

Related

Researching Javascript DEOPT reasons in Chrome 79 for a pet project

I've been tinkering with a Javascript chess engine for a while. Yeah yeah I know (chuckles), not the best platform for that sorta thing. It's a bit of a pet project, I'm enjoying the academic exercise and am intrigued by the challenge of approaching compiled language speeds. There are other quirky challenges in Javascript, like the lack of 64bit integers, that make it unfit for chess, but paradoxically interesting, too.
A while back I realized that it was extremely important to be careful with constructs, function parameters, etc. Everything matters in chess programming, but it seems that a lot matters when working with JIT compilers (V8 Turbofan) via Javascript in Chrome.
Via some traces, I'm seeing some eager DEOPTs that I'm having trouble figuring out how to avoid.
DEOPT eager, wrong map
The code that's referenced by the trace:
if (validMoves.length) { ...do some stuff... }
The trace points directly to the validMoves.length argument of the IF conditional. validMoves is only ever an empty array [] or an array of move objects [{Move},{Move},...]
Would an empty array [] kick off a DEOPT?
Incidentally, I have lots of lazy and soft DEOPTs, but if I understand correctly, these are not so crucial and just part of how V8 wraps its head around my code before ultimately optimizing it; in --trace-opt, the functions with soft,lazy DEOPTs, do seem to eventually be optimized by Turbofan, and perhaps don't hurt performance in the long run so much. (For that matter, the eager DEOPT'ed functions seem to eventually get reoptimized, too.) Is this a correct assessment?
Lastly, I have found at times that by breaking up functions that have shown DEOPTs, into multiple smaller function calls, I've had notable performance gains. From this I've inferred that the larger more complex functions are having trouble getting optimized and that by breaking them up, the smaller compartmentalized functions are being optimized and thus feeding my gains. Does that sound reasonable?
the lack of 64bit integers
Well, there are BigInts now :-)
(But in most engines/cases they're not suitable for high-performance operations yet.)
Would an empty array [] kick off a DEOPT?
Generally no. There are, however, different internal representations of arrays, so that may or may not be what's going on there.
[lazy, soft, eager...] Is this a correct assessment?
Generally yes. Usually you don't have to worry about deopts, especially for long-running programs that experience a few deopts early on. This is true for all the adjectives that --trace-deopt reports -- those are all just internal details. ("eager" and "lazy" are direct opposites of each other and simply indicate whether the activation of the function that had to be deoptimized was top-of-stack or not. "soft" is a particular reason for a deopt, namely a lack of type feedback, and V8 choosing to deoptimize instead of generating "optimized" code despite lack of type feedback, which wouldn't be very optimized at all.)
There are very few cases where you, as a JavaScript developer, might want to care about deopts. One example is when you've encountered a case where the same deopt happens over and over again. That's a bug in V8 when it happens; these "deopt loops" are rare, but occasionally they do occur. If you have found such a case, please file a bug with repro instructions.
Another case is when every CPU cycle matters, especially during startup / in short-running applications, and some costly functions gets deoptimized for a reason that might be avoidable. That doesn't seem to be your case though.
[breaking up functions...] Does that sound reasonable?
Breaking up functions can be beneficial, yes; especially if the functions you started with were huge. Generally, functions of all sizes get optimized; obviously larger functions take longer to optimize. This is a tricky area with no simple answers; if functions are too small then that's not helpful for performance either. V8 will perform some inlining, but the decisions are based on heuristics that naturally aren't always perfect. In my experience, manually splitting functions can in particular pay off for long-running loops (where you'd put the loop into its own function).
EDIT: to elaborate on the last point as requested, here's an example: instead of
function big() {
for (...) {
// long-running loop
}
/* lots more stuff... */
}
You'd split it as:
function loop() {
for (...) {
// same loop as before
}
}
function outer() {
loop();
/* same other stuff as before */
}
For a short loop, this is totally unnecessary, but if significant time is spent in the loop and the overall size of the function is large, then this split allows optimization to happen in more fine-grained chunks and with fewer ("soft") deopts.
And to be perfectly clear: I only recommend doing this if you are seeing a particular problem (e.g.: --trace-opt telling you that your biggest function is optimized two or more times, taking a second each time). Please don't walk away from reading this answer thinking "everyone should always split their functions", that's not at all what I'm saying. In extreme cases of huge functions, splitting them can be beneficial.

Using bind to clear the call stack during a CPS computation

EDIT: This question of mine has shown out to be quite ill-posed. I still believe that, especially going through the comments, it may provide some food for thoughts, but if enough votes will be reached to have it closed, I'll understand.
During some study of a very interesting treatise about ways to unwind the call stack by emulating call/cc in JavaScript (What's the difference between a continuation and a callback?) I was confronted with what seems to be a radical improvement of the way mostly used to make JS function calls asynchronous.
The most popular way is setTimeout(fun, 0). This construction takes the invocation of fun out of the current thread of execution and allows other jobs in the event queue to have their go. However, when its turn comes, fun maintains its whole call stack in all situations.
But if, as the above mentioned treatise does, the code is changed to setTimeout.bind(null, fun, 0) and we are programming in continuation-passing style (no return instructions to remember), then the call stack of fun is cleared and brought back to depth 1.
It is possible to see all this at work in an example. Verified in Chrome, FF, IE, Opera.
The sample HTML page is very simple to download and run in the browser with the developer tools open. There are two pausing instructions at rows 18 and 42, where you can observe the differences between the call stacks maintained by the two invocations of setTimeout.
The question is: how come that setTimeout.bind() behaves so radically different from a plain setTimeout invocation? Can someone illustrate what is going on?

Debugging Techniques in JavaScript. Async Callbacks

In an existing Backbone/jQuery/CoffeeScript app I am working on, it appears there is a function (Backbone.Collection.fetch()) called multiple times (sometimes number may vary). I think it might be a timing thing as I am doing alot of nested callbacks (like AJAX etc) and its becoming hard to debug. I should probably try to convert the code to use jQuery deferred but in the mean time, what can I do?
Just tried walking through the code in Chrome, but it appears the code is jumping here and there, maybe its processing different callbacks at the same time?
I am thinking maybe I add a console.log to every function + its arguments, but there must be a better way?
You can add a stack trace to that fetch() function, and see where it's being called from. There are a number of decent stack trace implementations for JS. I've had good success with
Eric Wendelin's version, but there are plenty of others.
With the stack trace, perhaps you can at least see what the most common paths are into that function, and that might help narrow down where to search. It might even make clear the underlying culprit.

IE displays Script error on recursive function

Hy guys!
I have a recursive function that takes time to perform. The IE is "thinking" that function is like a loop with no end.
What should I do to make IE don't show the error?
Thks guys!
You cannot, it is a functionality in most browsers to give the user a way out if he visits a webpage with javascript that ties up his cpu for too long and thus kills the browser.
The only way around it, is to performance optimize your code so it goes faster :)
I am assuming the "error" look like this, otherwise my answer is wrong:
Javascript in your browser runs in a single thread. If you have some kind of code running (recursive or otherwise) that does not yield to the browser every now and then, the browser will pause the script and ask the user whether they want to stop the code or continue. If this didn't happen there would be no way for the user to regain control (if you like your long-running code is running on the same thread as the UI, that is, the webpage). That's why ajax calls are structured in such a way that your code does not wait (that is, block) for the result, but instead a callback function is, well, called back with the results.
So how do you yield in a long-running piece of code? Several ways (ajax is one example) but the most popular is to use setTimeout in some way. Unfortunately it's just not that easy to explain how to use it without knowing what you are doing exactly. Any small examples I could give would be artificial.
So the strict answer to your question is "rewrite your code into execution chunks such t
hat there's no one chunk that takes a long time to execute".

Pausing JavaScript execution for animation of code

I'm having an interesting but difficult problem with my JavaScript code. Basically, I'm trying to create an animation of a simple algorithm using JavaScript (a sorting algorithm, if you're wondering) for educational reasons. I've already got all of the animation code written (using RaphaelJS), and it all works fine. The trouble is getting the animations of the algorithm to happen at the right time. JavaScript doesn't really have any way to "pause" execution, so I can't really step through the algorithm slowly, playing animations at each step. It's obviously much more valuable from an educational perspective if the algorithm proceeds at a pace the student can comprehend.
There are two ways to solve this problem that I can think of, and both suck. The first is to use some crazy setTimeout() code. This would probably be very difficult -- lots of strange code transformations would be needed to associate the different parts of the algorithm with correct timeouts. I've already tried to do this a little bit, and it gets very complicated for a non-trivial algorithm.
The second is to busy-wait. This would probably also work. The problem is that busy waiting is a pretty bad idea in JavaScript code -- I actually crashed Firefox when I was testing out this alternative. Basically, I'm wondering if there's another solution here that I'm overlooking. Bonus points if the solution is client-side only, since the amount of freedom I have to serve stuff other than static html and javascript on the school server is questionable.
It's obviously much more valuable from an educational perspective if the algorithm proceeds at a pace the student can comprehend.
What about using links/buttons e.g. < > to allow the user to step through the code by clicking prev/next?
Maybe the only viable workaround and may make more sense for the end user.
Maybe this is too simple to do what you want it to do, but what if you put the segment of code that you want to run between stops into a function, and call that function with the push/click of a button on the page: onclick="runAnimationPiece()"
Your code would need to hold some state to know where it left off from the last time the function ran.
And if you need to run different functions for different pieces of the animation, say, for instance, the first piece should be generated by foo1() and second piece by foo2(), you can create a counter and a function which calls the appropriate animation function (foo1() or foo2(), etc.) based on the counter.

Categories

Resources