describe('Maestro', function () {
var numArray = ['5018', '5020', '5038', '6304'];
var should = chai.should;
var string = '012344555389638968953769839'
var l = 12;
// Write full test coverage for the Maestro card
for (var i = 0; i < numArray.length; i++) {
var currentPrefix = numArray[i];
for (var length = l; length <= 19; length++) {
it(`has a prefix of ${numArray[i]} and a length of ${length}`, function () {
detectNetwork(numArray[i] + string.substring(0, length - 4)).should.equal('Maestro')
});
}
}
})
It's been after hours for Hack Reactors TAs to give me a hand and I've been battling this for about 6 hours.
I have rewritten this test several different times. I've hardcoded, I've written every test individually (which I did get to pass, but I know the next problem requires about 800 prefixes and varying lengths, so hard coding isn't an option there). This is the first time I've been introduced to Mocha testing and chai but have had other credit cards pass using this logic.
Any help would be appreciated.
It seems you have not import the package chai correctly.
The error says can't read should of undefined. That is, the program is getting chai as undefined.
To avoid the problem ensure you have the variable chai imported like this:
var chai = require("chai");
And also you have done npm install chai.
I'm trying to sum up numbers using two different variants, without web workers and using web workers.
I expect the web workers version to be about ten times faster because I divide the interval into ten intervals, but it's not like that. It's about ten times slower. I do not understand why. Does the ten web workers work in parallel?
var sum1 = 0, sum2 = 0, nrElements = 10000000;
var t0 = performance.now();
for (var i=0; i < nrElements; i++) {
sum1 += i;
}
var t1 = performance.now();
console.log("Version1 - " + (t1 - t0) + " sum: " + sum1)
var t3 = performance.now();
var n, running;
var pas = 0;
running = 0;
for (n = 0; n < 10; ++n) {
let workers = new Worker("worker.js");
pozStart = pas;
pas += nrElements / 10;
pozStop = pas;
workers.postMessage({start: pozStart, stop: pozStop});
workers.onmessage = workerDone;
++running;
}
function workerDone(e) {
--running;
sum2 += e.data[1];
if (running === 0) {
var t4 = performance.now();
console.log("Version2 - " + (t4 - t3) + " sum: " + sum2)
}
}
//worker.js
onmessage = function(e) {
var sum=0;
for(let i= e.data.start; i < e.data.stop; i++)
{
sum += i;
}
postMessage(["r",sum]);
}
There are many things here that could make your observations vary a lot, like how browsers do optimize your code (particularly for such simple for loops), but to answer the general question Why running through Web-Workers takes more time, then ...
You are running 10 workers in parallel. If your computer is not able to run ten threads concurrently, all your threads will indeed get slowed down.
As a rule of thumb, never exceed navigator.hardwareConcurrency- 1 number of concurrent Web Workers on the same page.
Initializing a WebWorker is not such a fast operation. It includes a Network request, parsing of the js file, building of the context. So initialize it once, and then ask them multiple times to do what you want.
But note that even then, you'll probably have slower results using the Workers with such a small operation. The simple operation
worker.postMessage(); // in main
self.onmessage = e => self.postMessage(); // in worker.js
worker.onmessage = e => ... // back in main
will already take place in at least 3 different event loops, since messages are received in the event loop following the one they've been sent from.
Unless you have some operations that will take seconds, offloading on worker might indeed get slower.
But even if slower, having your job offloaded in Worker allows the main thread to be free, and these 30ms will cause a drop of two frames, which could make something like an animation look jerky, so keep on using WebWorkers, but not for the speed.
A online tool, such as JSCompress, will reduce code size up to 80%. It's easy to notice that the result, compressed code, removes space. Beyond the removal of EOL and ' ' characters, is there any other trickery needed to minify a js file?
Example compressed:
function glow(e){$("#"+e).fadeIn(700,function(){$(this).fadeOut(700)})}function startLevel(){ptrn=[],pos=0,setLevel(lvl),$("#mg-lvl").fadeOut("slow",function(){$("#mg-contain").prop("onclick",null).off("click"),$("#mg-contain").css("cursor","default"),$(this).text("Level "+lvl+": "+ptrn.length+" blink(s)."),$(this).fadeIn("slow"),showLevel(0)})}function setLevel(e){ptrn.push(Math.floor(3*Math.random()+1)),0==e||setLevel(--e)}function showLevel(e){$("#b"+ptrn[e]+"c").fadeOut(speed,function(){$("#ball_"+ptrn[e]).fadeOut(speed,function(){$("#b"+ptrn[e]+"c").fadeIn(speed),$(this).fadeIn(speed,function(){e+1<ptrn.length&&showLevel(++e,speed)})})}),e+1==ptrn.length&&setTimeout(bindKeys(1),ptrn.length*speed+15)}function bindKeys(e){for(var e=1;e<4;e++)bind(e)}function bind(e){$("#ball_"+e).on("click",function(){$("#b"+e+"c").fadeOut(speed,function(){$("#ball_"+e).fadeOut(speed,function(){$("#ball_"+e).fadeIn(speed),$("#b"+e+"c").fadeIn(speed),referee(e)&&unbind()})})})}function referee(e){if(pos<ptrn.length&&(e===ptrn[pos]?$("#mg-score").text(parseInt($("#mg-score").text())+1):end()),++pos==ptrn.length)return++lvl,speed-=40,!0}function unbind(){for(var e=1;e<4;e++)$("#ball_"+e).off();startLevel()}function nestedFade(e,n,t){e[n]&&$(e[n]).fadeOut("fast",function(){t[n]&&($(e),t[n]),nestedFade(e,++n,t)})}function end(){for(var e=[],n=[],t=1;t<4;t++)e.push("#b"+t+"c"),e.push("#ball_"+t),n.push(null);e.push("#mg-contain"),n.push('.fadeOut("slow")'),e.push("#mg-obj"),n.push(".fadeOut('slow')"),e.push("#bg-ball-container"),n.push(".toggle()"),nestedFade(e,0,n)}var ptrn=[],pos=0,lvl=1,speed=400,b1=setInterval(function(){glow("ball_1b",700)}),b2=setInterval(function(){glow("ball_2b",700)}),b3=setInterval(function(){glow("ball_3b",700)});
Example uncompressed:
var ptrn = [];
var pos = 0;
var lvl = 1;
var speed = 400;
/* make balls glow */
function glow(id)
{
$('#'+id).fadeIn(700, function(){$(this).fadeOut(700);})
}
var b1 = setInterval(function(){ glow('ball_1b',700) ,1500});
var b2 = setInterval(function(){ glow('ball_2b',700) ,1500});
var b3 = setInterval(function(){ glow('ball_3b',700) ,1500});
/* end */
function startLevel()
{
ptrn = [];
pos = 0;
/* set pattern for the level */
setLevel(lvl);
/* display prompt for level */
$('#mg-lvl').fadeOut("slow", function(){
$('#mg-contain').prop('onclick',null).off('click');
$('#mg-contain').css('cursor','default');
$(this).text("Level " + lvl + ": " + ptrn.length + " blink(s).");
$(this).fadeIn('slow');
/* play back the pattern for user to play */
showLevel(0); //TODO: use promise and deferred pattern to pull this out of fade function.
});
}
function setLevel(lvl)
{
ptrn.push(Math.floor((Math.random() * 3) + 1));
(lvl == 0 ) ? null : setLevel(--lvl);
}
function showLevel(i)
{
/* blink the balls */
$('#b'+ptrn[i]+'c').fadeOut(speed, function(){
$('#ball_'+ptrn[i]).fadeOut(speed, function(){
$('#b'+ptrn[i]+'c').fadeIn(speed);
$(this).fadeIn(speed, function(){
if(i+1<ptrn.length)
showLevel(++i,speed);
});
});
});
if( (i+1) == ptrn.length)
setTimeout( bindKeys(1), ptrn.length*speed+15) //after the pattern is revealed bind the clicker
}
function bindKeys(i)
{
for(var i=1;i<4;i++)
bind(i);
}
function bind(i)
{
$('#ball_'+i).on('click', function() {
$('#b'+i+'c').fadeOut(speed, function() {
$('#ball_'+i).fadeOut(speed, function() {
$('#ball_'+i).fadeIn(speed);
$('#b'+i+'c').fadeIn(speed);
if(referee(i))
unbind();
});
});
});
}
function referee(val)
{
if(pos < ptrn.length){
( val === ptrn[pos] ) ? $('#mg-score').text(parseInt($('#mg-score').text())+1) : end();
}
if(++pos == ptrn.length)
{
++lvl;
speed-=40;
return true;
}
}
function unbind()
{
for(var i=1;i<4;i++)
$( "#ball_"+i).off();
startLevel();
}
function nestedFade(id,i,func)
{
(!id[i]) ? 0 : $(id[i]).fadeOut('fast',function(){ if(func[i])
{$(id)+func[i];};nestedFade(id,++i,func);})
}
function end()
{
var id = [];
var func = [];
for(var i=1;i<4;i++){
id.push('#b'+i+'c');
id.push('#ball_'+i);
func.push(null)
}
id.push('#mg-contain');
func.push('.fadeOut("slow")');
id.push('#mg-obj');
func.push(".fadeOut('slow')");
id.push('#bg-ball-container');
func.push(".toggle()");
nestedFade(id,0,func);
}
Saves 32% on file size...and if that is the case, is it a fair assumption then that writing less is doing more for the end user?
The same way you can 'minify' a file to reduce its size, you can also 'uglify' a file, which takes your code and shortens things like variable names to the same end: reduce file size by reducing the number of characters in it (not just removing line breaks and space characters).
While it will reduce loadtime for a user, it's not a great practice to write minified/uglified-style code off the bat. That's why in almost any professional build/deploy process, you take your clear, descriptive code and then run your build processes to reduce the size of your files and eventually deploy versions that your end user will have a quicker time loading. You can always write your regular code, then run a compression process like the one you described, save it into a "public" folder and upload that for users to have access to, rather than your fleshed out code.
All a minifier will do is remove white space, which like you said, is ' ' and EOL characters. I believe you may be thinking of file compression tools such as a .zip file with the way your question is worded. Such file types (.zip) will find common strings in your file, and put references to the original string rather than having it written out 10 times. Meaning if the string "I like cake" shows up 4 times in your file, it will have "I like cake" in one location, and the other three locations will reference that first location, shortening the length of the file and therefore decreasing its size.
Well the main reason JS, CSS and HTML get's minified is to decrease the size of the files transmitted from server to client when a client requests a webpage. This decrease in size will allow for a faster load time. So technically writing less is more for a webpages load time, but realistically the effect of you as a developer consciously writing shorter code to minimize file size will either a.) Be to minimal a change to actually make a difference or b.) lead to loss of functionality or bugs due to the focus being on cutting down code length, not code quality.
Me and my friend are making a node.js game, and we have been testing cpu, but after profiling this process called zlib is sucking most of the CPU/RAM
3 clients connected to a game is fine, but when 12~13 players are connected it uses 58% where zlib is using about 30% of this cpu.
inclusive self name
ticks total ticks total
64775 58.5% 64775 58.5% /lib/x86_64-linux-gnu/libc-2.19.so
25001 22.6% 224 0.2% LazyCompile: *callback zlib.js:409
//this one is a different zlib
7435 6.7% 82 0.1% LazyCompile: ~callback zlib.js:409
Is there any way to decrease the cpu usage from this? or is there a reason why it is increasing so much.
I have done some reading and I am told it is from socket.io so here is our section of socket sending most of the data.
for (var i = 0; i < users.length; i++) {
if (u.room == users[i].room && users[i].x + users[i].radius >= u.x - u.screenWidth / 2 - 20 && users[i].x - users[i].radius <= u.x + u.screenWidth / 2 + 20 && users[i].y + users[i].radius >= u.y - u.screenHeight / 2 - 20 && users[i].y - users[i].radius <= u.y + u.screenHeight / 2 + 20) {
if (users[i].id == u.id) {
visiblePlayers.push({
x: users[i].x,
y: users[i].y,
angle: users[i].angle,
hue: users[i].hue,
radius: users[i].radius,
squeeze: users[i].squeeze,
name: users[i].name,
dead: users[i].dead,
isPlayer: true,
kills: users[i].kills
});
} else {
visiblePlayers.push({
x: users[i].x,
y: users[i].y,
angle: users[i].angle,
hue: users[i].hue,
radius: users[i].radius,
squeeze: users[i].squeeze,
name: users[i].name,
dead: users[i].dead
});
}
// SEND DYING INFO: (FOR OFFLINE ANIMATION):
if (users[i].dying) {
visiblePlayers[visiblePlayers.length - 1].dying = true;
}
}
}
var visibleEnergy = [];
for (var i = 0; i < energies.length; i++) {
if (u.firstSend || (energies[i].updated && energies[i].room == u.room)) {
var anim = energies[i].animate;
if (u.firstSend)
anim = true;
visibleEnergy.push({
x: energies[i].x,
y: energies[i].y,
radius: energies[i].radius,
index: i,
animate: anim,
hue: energies[i].hue,
room: energies[i].room
});
}
}
// SEND PLAYER UPDATES TO CLIENTS:
sockets[u.id].emit('serverTellPlayerMove', visiblePlayers,
visibleEnergy);
Zlib is one of out problems, but also if there are any other optimisation methods to decrease server CPU.
Extra: the formatting of checking users has been answered in StackExchange at https://codereview.stackexchange.com/questions/107922/node-js-cpu-issue. We just need help if there are any methods to decrease the zlib cpu usage.
Thanks.
zlib is a widely used compression library. The most likely reason you're seeing lots of CPU usage there is a lot of compressed network traffic. That's desirable because CPU is generally 'cheaper' than network traffic. Other areas that are likely candidates for heavy zlib usage would be compressed files on disk being loaded through node.js's zlib module, or perhaps if you're doing server-side decompression of PNG images which also commonly uses zlib.
If you find the zlib 'tax' is too much for your particular application, perhaps you could offload the decompression to another process. You could use a few node.js services in front of your main server whose purpose is purely to connect to clients. Then have them talk to your server in uncompressed, 'raw' format which your server has an easier time understanding.
You don't mention if this is actually causing you problems yet. I wouldn't necessarily worry about it yet. This kind of single process scalability is a downside of using node.js, and the only solution is to split up your service into smaller parts that can be spread across multiple cores or even multiple servers.
In case you are not familiar with CoffeeScript, here's the JavaScript version of p1.coffee and p2.coffee mentioned below.
Piping a node.js script's stdout to another's stdin doesn't seem to work. I have p1.coffee which outputs numbers to stdout as fast as it can:
i = 0
(->
i += 1
process.stdout.write "#{i} "
)() while true
I now have p2.coffee which does exactly what's like a cat:
process.stdin.on 'end', -> console.log "EOF"
process.stdin.pipe(process.stdout)
Now if I pipeline them together, it displays only the first number and "blocks" there:
> coffee p1.coffee | coffee p2.coffee
1
I'm using node v0.10.31 on Windows if that matters.
That might be a Windows specific issue. I tried the following with Node.js v0.10.31 on OS X and it worked fine:
// cat.js
process.stdin.once('end', function () {
console.log('EOF');
});
process.stdin.pipe(process.stdout);
// count.js
var i = 0;
while (true) {
process.stdout.write(i++ + ' ');
}
and piped the output of count.js to cat.js:
node count.js | node cat.js
Also note that your CoffeeScript compiles to:
var i;
i = 0;
while (true) {
(function() {
i += 1;
return process.stdout.write("" + i + " ");
})();
}
Creating functions within loops makes your code slower. You could do the following instead:
i = 0
loop process.stdout.write("#{i += 1} ")