Javascript for loop never ends (10^10 itenerations) - javascript

I have a 'for' loop wich have to loop around 10000000000 times so that i get the disered result.
However, it ends up all the time freezing the browser ...
It's not like that 'for' is working infinitly but as i told, it's very long
Is there some way to solve my problem with javascript or i should use another language ?

In a compiled language and if you do virtually nothing in the loop, you can achieve 1,000,000,000 iterations a second on a desktop processor. So your loop would take 10 seconds.
If your Javascript environment is interpreted (and not compiled), you probably won't get more than 10,000,000 iterations and your loop will take 1000 seconds (16 minutes).
If you additionally have somewhat more expensive operations within the loop (and Javascript is likely to allocate memory for simple operations, which is expensive), you're in the order of 1,000,000 iterations per seconds and your code takes 10,000 seconds (close to 3 hours).
You might want to think about a better algorithm...

The issue that you are seeing is because javascript is single threaded in the browser. Your for loop is holding on to the thread for the entire time that it is running. The problem is that this thread also handles interactions with the interface. There may be other possibilities, but the two ways that I can think of to fix this would be:
Use a Web Worker (docs), this solution will not work for older browsers though
If possible, break your loop into smaller chunks that can be ran using setTimeout. After each chunk is processed, use setTimeout to schedule the next chunk to be processed in say 100ms. You will need to play with the numbers, but that should free up the thread so that it can respond to events. This will make the calculation take longer but should make it so the browser doesn't freeze up.

Don't do it. To run this kind of Javascript code in a browser makes no sense. If you really want to do this on the client side, you should consider writing some kind of browser extension, where you have more control on the CPU and local storage.
You might want to separate that loop in smaller chunks and run them sequentially, with an appropriate progress system. If you are talking about a loop, a multithreaded system will not help you, assuming the result n+1 is based on the n result.
Consider using a server-side script with a queue or job mechanism and just push notifications to the client. As Teemu said, the time (even in a fast paced situation) is huge.

Related

Why is Non blocking asynchronous single-threaded faster for IO than blocking multi-threaded for some applications

It helps me understand things by using real world comparison, in this case fastfood.
In java, for synchronous blocking I understand that each request processed by a thread can only be completed one at a time. Like ordering through a drive through, so if im tenth in line I have to wait for the 9 cars ahead of me. But, I can open up more threads such that multiple orders are completed simultaneously.
In javascript you can have asynchronous non-blocking but single threaded. As I understand it, multiple requests are made, and those request are immediately accepted, but the request is processed by some background process at some later time before returning. I don't understand how this would be faster. If you order 10 burgers at the same time the 10 requests would be put in immediately but since there is only one cook (single thread) it still takes the same time to create the 10 burgers.
I mean I understand the reasoning, of why non blocking async single thread "should" be faster for somethings, but the more I ask myself questions the less I understand it which makes me not understand it.
I really dont understand how non blocking async single threaded can be faster than sync blocking multithreaded for any type of application including IO.
Non-blocking async single threaded is sometimes faster
That's unlikely. Where are you getting this from?
In multi-threaded synchronous I/O, this is roughly how it works:
The OS and appserver platform (e.g. a JVM) work together to create 10 threads. These are data structures represented in memory, and a scheduler running at the kernel/OS level will use these data structures to tell one of your CPU cores to 'jump to' some point in the code to run the commands it finds there.
The datastructure that represents a thread contains more or less the following items:
What is the location in memory of the instruction we were running
The entire 'stack'. If some function invokes a second function, then we need to remember all local variables and the point we were at in that original method, so that when the second method 'returns', it knows how to do that. e.g. your average java program is probably ~20 methods deep, so that's 20x the local vars, 20 places in code to track. This is all done on stacks. Each thread has one. They tend to be fixed size for the entire app.
What cache page(s) were spun up in the local cache of the core running this code?
The code in the thread is written as follows: All commands to interact with 'resources' (which are orders of magnitude slower than your CPU; think network packets, disk access, etc) are specified to either return the data requested immediately (only possible if everything you asked for is already available and in memory). If that is impossible, because the data you wanted just isn't there yet (let's say the packet carrying the data you want is still on the wire, heading to your network card), there's only one thing to do for the code that powers the 'get me network data' function: Wait until that packet arrives and makes its way into memory.
To not just do nothing at all, the OS/CPU will work together to take that datastructure that represents the thread, freeze it, find another such frozen datastructure, unfreeze it, and jump to the 'where did we leave things' point in the code.
That's a 'thread switch': Core A was running thread 1. Now core A is running thread 2.
The thread switch involves moving a bunch of memory around: All those 'live' cached pages, and that stack, need to be near that core for the CPU to do the job, so that's a CPU loading in a bunch of pages from main memory, which does take some time. Not a lot (nanoseconds), but not zero either. Modern CPUs can only operate on the data loaded in a nearby cachepage (which are ~64k to 1MB in size, no more than that, a thousand+ times less than what your RAM sticks can store).
In single-threaded asynchronous I/O, this is roughly how it works:
There's still a thread of course (all things run in one), but this time the app in question doesn't multithread at all. Instead, it, itself, creates the data structures required to track multiple incoming connections, and, crucially, the primitives used to ask for data work differently. Remember that in the synchronous case, if the code asks for the next bunch of bytes from the network connection then the thread will end up 'freezing' (telling the kernel to find some other work to do) until the data is there. In asynchronous modes, instead the data is returned if available, but if not available, the function 'give me some data!' still returns, but it just says: Sorry bud. I have 0 new bytes for you.
The app itself will then decide to go work on some other connection, and in that way, a single thread can manage a bunch of connections: Is there data for connection #1? Yes, great, I shall process this. No? Oh, okay. Is there data for connection #2? and so on and so forth.
Note that, if data arrives on, say, connection #5, then this one thread, to do the job of handling this incoming data, will presumably need to load, from memory, a bunch of state info, and may need to write it.
For example, let's say you are processing an image, and half of the PNG data arrives on the wire. There's not a lot you can do with it, so this one thread will create a buffer and store half of the PNG inside it. As it then hops to another connection, it needs to load the ~15% of the image it alrady got, and add onto that buffer the 10% of the image that just arrived in a network packet.
This app is also causing a bunch of memory to be moved around into and out of cache pages just the same, so in that sense it's not all that different, and if you want to handle 100k things at once, you're inevitably going to end up having to move stuff into and out of cache pages.
So what is the difference? Can you put it in fry cook terms?
Not really, no. It's all just data structures.
The key difference is in what gets moved into and out of those cache pages.
In the case of async it is exactly what the code you wrote wants to buffer. No more, no less.
In the case of synchronous, it's that 'datastructure representing a thread'.
Take java, for example: That means at the very least the entire stack for that thread. That's, depending on the -Xss parameter, about 128k worth of data. So, if you have 100k connections to be handled simultaneously, that's 12.8GB of RAM just for those stacks!
If those incoming images really are all only about 4k in size, you could have done it with 4k buffers, for only 0.4GB of memory needed at most, if you handrolled that by going async.
That is where the gain lies for async: By handrolling your buffers, you can't avoid moving memory into and out of cache pages, but you can ensure it's smaller chunks. and that will be faster.
Of course, to really make it faster, the buffer for storing state in the async model needs to be small (not much point to this if you need to save 128k into memory before you can operate on it, that's how large those stacks were already), and you need to handle so many things at once (10k+ simultaneous).
There's a reason we don't write all code in assembler or why memory managed languages are popular: Handrolling such concerns is tedious and error-prone. You shouldn't do it unless the benefits are clear.
That's why synchronous is usually the better option, and in practice, often actually faster (those OS thread schedulers are written by expert coders and tweaked extremely well. You don't stand a chance to replicate their work) - that whole 'by handrolling my buffers I can reduce the # of bytes that need to be moved around a ton!' thing needs to outweigh the losses.
In addition, async is complicated as a programming model.
In async mode, you can never block. Wanna do a quick DB query? That could block, so you can't do that, you have to write your code as: Okay, fire off this job, and here's some code to run when it gets back. You can't 'wait for an answer', because in async land, waiting is not allowed.
In async mode, anytime you ask for data, you need to be capable of dealing with getting half of what you wanted. In synchronized mode, if you ask for 4k, you get 4k. The fact that your thread may freeze during this task until the 4k is available is not something you need to worry about, you write your code as if it just arrives as you ask for it, complete.
Bbbuutt... fry cooks!
Look, CPU design just isn't simple enough to put in terms of a restaurant like this.
You are mentally moving the bottleneck from your process (the burger orderer) to the other process (the burger maker).
This will not make your application faster.
When considering the single-threaded async model, the real benefit is that your process is not blocked while waiting for the other process.
In other words, do not associate async with the word fast but with the word free. Free to do other work.

JavaScript: trying to create a well-behaved background job, but it gets too little time to run while rest of the system is mostly idle?

In a browser, I am trying to make a well-behaved background job like this:
function run() {
var system = new System();
setInterval(function() { system.step(); }, 0);
}
It doesn't matter what that System object is or what the step function does [except it needs to interact with the UI, in my case, update a canvas to run Conway's Game of Life in the background], the activity is performed slowly and I want it to run faster. But I already specified no wait time in the setInterval, and yet, when I check the profiling tool in Chrome it tells me the whole thing is 80% idle:
Is there a way to make it do less idle time and perform my job more quickly on a best effort basis? Or do I have to make my own infinite loop and then somehow yield back time to the event loop on a regular basis?
UPDATE: It was proposed to use requestIdleCallback, and doing that makes it actually worse. The activity is noticably slower, even if the profiling data isn't very obvious about it, but indeed the idle time has increased:
UPDATE: It was then proposed to use requestAnimationFrame, and I find that once again the slowness and idleness is the same as the requestIdleCallback method, and both run at about half the speed that I get from the standard setInterval.
PS: I have updated all the timings to be comparable, all three now timing about 10 seconds of the same code running. I had the suspicion that perhaps the recursive re-scheduling might be the cause for the greater slowness, but I ruled that out, as the recursive setTimeout call is about the same speed as the setInterval method, and both are about twice as fast as these new request*Callback methods.
I did find a viable solution for what I'm doing in practice, and I will provide my own answer later, but will wait for a moment longer.
OK, unless somebody comes with another answer this here would be my FINAL UPDATE: I have once again measured all 4 options and measured the elapsed time to complete a reasonable chunk of work. The results are here:
setTimeout - 31.056 s
setInterval - 23.424 s
requestIdleCallback - 68.149 s
requestAnimationFrame - 68.177 s
Which provides objective data to my impression above that the two new methods with request* will perform worse.
I also have my own practical solution which allows me to complete the same amount of work in 55 ms (0.055 s), i.e., > 500 times faster, and still be relatively well behaved. Will report on that in a while. But wonder what anybody else can figure out here?
I think this is really dependent on what exactly you are trying to achieve though.
For example, you could initialize your web-worker on loading the page and make it run the background-job, if need be, then communicate the progress or status of the job to the main thread of your browser. If you don't like the use of post-message for communication between the threads, consider user Comlink
Web worker
Comlink
However, if the background job you intend to do isn't something worth a web-worker. You could use the requestIdleCallback API. I think it fits perfectly with what you mentioned here since you can already make it recursive. You would not need a timer anymore and the browser can help you schedule the task in such a way that it doesn't affect the rendering of your page (by keeping everything with 60fps).
Something like =>
function run() {
// whatever you want to keep doing
requestIdleCallback(run)
}
You can read more about requestIdleCallback on MDN.
OK, I really am not trying to prevent others to get the bounty, but as you can see from the details I added to my question, none of these methods allow high rate execution of the callback.
In principle the setInterval is the most efficient way to do it, as we already do not need to re-schedule the next call back all the time. But it is a small difference only. Notably requestIdleCallback and requestAnimationFrame are the worst when you want to be rapidly called back.
So, what needs to be done is instead of executing only a tiny amount of work and then expect to be called back quickly, we need to batch up more work. Problem is we don't know exactly how much work we should batch up before it is too much. That can probably in most cases be figured out with trial and error.
Dynamically one might take timing probes to find out how quickly we are being called back again and preemptively exit the work (loop of some kind) when the time between the call-backs is expired.

Using setTimeout to prevent long running script bugs in IE8 - why does it depend on the interval?

I'm trying to write some JavaScript to run against IE8. It's to do with sorting a moderately large set of data (actually, for 99% of users its a very small set of data - but as always, there's some edge cases) . I've been investigating ways to execute a long script on IE8 without either blocking the UI or causing the 'Long Running Script' message.
A popular solution is to use window.setTimeout to stagger function calls and then return that variable at the end asynchronously. The common advice is to write a recursive function and call it with
window.setTimeout(fn, 1);
because this is supposed to add the call to the thread's event queue. UI operations will be interleaved with setTimeout calls and the browser will remain responsive. IE8 won't moan, the idea goes, because its statement counter is reset when the timeout is invoked.
But I have a problem. I've found that in IE8, the long running script exception only disappears if the timeout is long enough.
I've written some functions that increment a number to 3 million using staggered function calls that each perform 50,000 n++ operations. These functions perform many operations (actually, massively more than even my worst use case), but none should break IE's documented 5 million instruction limit. Here's the thing, though: if I stagger the functions with a 1ms timeout, I get a long running script warning in IE8 half way through (after several function calls). If I stagger them with a 15ms timeout, I don't. How come? Is this something to do with the granularity of the Win32 timing API?
Here's a JSFiddle: http://jsfiddle.net/yb79vx7h/1/ , and an embedded version you can try for yourself in IE8
: http://jsfiddle.net/yb79vx7h/1/embedded/result/
Edit: curiously, I can replicate the same problems with the 15ms code if I count to 9 million using 600,000 iterations. That prompts the 'Stop running this script?' dialog in IE8 too. So it seems to be to do with the amount of actions versus the timeout length.

Want Javascript run while loop infinitely

I want the Javascript code can manipulate some object in html infinitely,
But, I can only use setTimeout("function()", 0) and can't use while(1)
examples:
while: https://gist.github.com/Asoul/e5dd3bd38eef4ca239cb
setTimeout : https://gist.github.com/Asoul/bda34fa2f70e4077ec12
I don't know why the while(1) can't work on my chrome
SetTimeout can work sometimes, but if there are many setTimeout in my code or some unknown reasons, it will lag.
example: http://www.csie.ntu.edu.tw/~b00902036/run_neo/run_neo.html
(Use up, left, right to play. I tried hard to avoid lags, but sometimes it still happen.)
I want use pure CSS, not canvas, and want the game can play without lags.
The main reason you cannot use while is because javascript is single-threaded. If you use while(1), the function will never exit and all other interactions are frozen.
SetTimeout can work sometimes, but if there are many setTimeout in my
code or some unknown reasons, it will lag.
This is also because of single-threaded nature of javascript, if there is a function taking long time to complete, it will dominate the main thread.
want the game can play without lags.
You need to avoid long-running operation inside all of your functions. If you cannot avoid that, try using setTimeout to split a long-running operation into many pieces.
For example: if you have a for-loop processing 100 records, you could split it into 10 separate iterations.

Two JavaScript timers vs one timer, for performance, is it worth dropping one?

In a web app which I'm building, I have two loosely related bits of code running in two separate timers every one second.
I'm looking to optimize the Javascript, is it worth merging these two timers into one or is that just over the top?
Realistically, am I going to increase any performance (considering that we don't know what sort a system a visitor is running ) by merging two 1 second intervals into one 1 second interval?
As I understand it, JavaScript is single threaded so the more things happening, the more these stack up and block other things from happening (timers especially). I just don't know whether one measly timer running every second is an issue at all.
The reason for keeping the two timers separate would purely be code readability, which is fine on the server side where you control the hardware but I don't know what sort of browser or hardware my visitors will be running.
Thanks.
In terms of the overall number of operations that can be completed, no, there isn't going to be a measurable difference. It is possible for there to be a perceived performance advantage in keeping multiple timers, however. The more code you have running synchronously in a single timer iteration, the longer all DOM updates and certain types of user interactions are "halted". By splitting these up into multiple timers, you allow other updates to take place in between timer iterations, and therefore the user gets a "smoother" experience.
Odds are in this case there won't even be a difference in perceived performance either, though, so I'd do it whichever way makes the code organization simpler.
If performance really is an issue you could just create 1 timer, and for example use that to call both functions:
function update()
{
A(); //Do your first task
B(); //Do the second
setTimeout("update()", 1000);
}
update();
However, how sure are you that the bottleneck is within this timer? Try to measure first, and dont optimise the wrong parts of your application.
I would bet that you'd increase performance by eliminating clock handling at the JS level. You certainly won't degrade performance and, with just one timer running, I'd think that you'd enhance code maintainability, if not readability. In the app I'm working on right now, I have one timer running to handle three tasks: a special kind of scrolling, changing the background image of perhaps 300 cells, and checking to see if it's time to refresh the page and issuing an AJAX request if so. That timer is running with a 1/10-sec interval and things are tight, for sure, but the code gets through all of those jobs, once in a while with one clock tick coming on top of the previous.
So I doubt you'll have any trouble with a 1-sec interval and just one tick handler.

Categories