Are there any good tutorials on how to write fast, efficient code for v8 (specifically, for node.js)?
What structures should I avoid using? What are the idioms that v8 optimises well?
From my experience:
It does inlining
Function call overhead is minimal (inlining)
What is expensive is to pass huge strings to functions, since those need to be copied and from my experience V8 isn't always as smart as it could be in this case
Scope lookup is expensive (surprise)
Don't do tricks e.g. I have a binary encoder for JS Object, cranking out some extra performance with bit shifting there (instead of Math.floor) latest Crankshaft (yes alpha, but still) runs the code 30% slower
Don't use magic. eval, arguments.callee etc. Those pretty much kill any optimization since code can no longer be inlined
Some of the new ES5 stuff e.g. .bind() is really slow in V8 at the moment
Somehow new Object() and new Array() are a bit faster currently (MICROoptimization, unless you're writing some crazy encoder stick with {} and [])
My rules:
Write good code
Write working code
Write code that works in strict mode (support still has to land, but when it does further optimization can be applied by V8)
If you're an JS expert and your already applying all good practices to your code, there's hardly anything you can do to improve performance.
If you encounter performance issues:
Verify them
Change the code / algorithm
And as a last resort: Write a C++ extension (and watch every commit to ry/node on GitHub since nobody cares whether some internal changes break your build)
The docs give a great answer: http://code.google.com/apis/v8/design.html
Understanding V8 is a set of slides from nodecamp.eu and gives very some interesting tips. In particular, I found the notes on avoiding "dictionary mode" useful i.e. it helps if you keep the "shape" of objects constant and don't add arbitrary properties to them.
You should also run node with --crankshaft --trace-opt --trace-bailout (the --crankshaft is only needed on 64-bit platforms e.g. OS X) to see whether V8 is "bailing" on JITing certain functions. There is a ton of other trace options including --trace-gc and various other GC tracing, which can be useful for optimisation.
Let me know if you have any specific questions about the slides above as they're a bit concise. :-) They're not mine but I've done some research about the areas they cover.
Related
I'm considering migrating my state management layer to using Map versus using a standard object.
From what I've read, Map is effectively a hash table whereas Objects use hidden classes under the hood. Generally it's advised, where the properties are likely to be dynamically added or removed it's more efficient to use Map.
I set up a little test and to my surprise accessing values in the Object version was faster.
https://jsfiddle.net/mfbx9da4/rk4hocwa/20/
The article also mentions fast and slow properties. Perhaps the reason my code sample in test1 is so fast is because it is using fast properties? This seems unlikely as the object has 100,000 keys. How can I tell if the object is using fast properties or dictionary lookup? Why would the Map version be slower?
And yes, in practice, looks like a premature optimization, root of all evil ... etc etc. However, I'm interested in the internals and curious to know of best practices of choosing Map over Object.
(V8 developer here.)
Beware of microbenchmarks, they are often misleading.
V8's object system is implemented the way it is because in many cases it turns out to be very fast -- as you can see here.
The primary reason why we recommend using Map for map-like use cases is because of non-local performance effects that the object system can exhibit when certain parts of the machinery get "overloaded". In a small test like the one you have created, you won't see this effect, because nothing else is going on. In a large app (using many objects with many properties in many different usage patterns), it's still not guaranteed (because it depends on what the rest of the app is doing) but there's a good chance that using Maps where appropriate will improve overall performance -- if the overall system previously happened to run into one of the unfortunate situations.
Another reason is that Maps handle deletion of entries much better than Objects do, because that's a use case their implementation explicitly anticipates as common.
That said, as you already noted, worrying about such details in the abstract is a case of premature optimization. If you have a performance problem, then profile your app to figure out where most time is being spent, and then focus on improving those areas. If you do end up suspecting that the use of objects-as-maps is causing issues, then I recommend to change the implementation in the app itself, and measure (with the real app!) whether it makes a difference.
(See here for a related, similarly misleading microbenchmark, where even the microbenchmark itself started producing opposite results after minor modifications: Why "Map" manipulation is much slower than "Object" in JavaScript (v8) for integer keys?. That's why we recommend benchmarking with real apps, not with simplistic miniature scenarios.)
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.
So I know that in Javascript instantiating a regex causes it to be compiled automatically and if that regex is stored in a variable it will be reused without recompiling. Example:
var re = /[Ff]oo|[Bb]ar/;
"Foo".match(re); // ["Foo"]
"Baz".match(re); // null
However, are duplicated regular expressions recompiled or does V8 (Chrome/Node.js) intelligently re-use them (like PHP does with preg_* functions)?
function isFooBar(str) {
return str.match(/[Ff]oo|[Bb]ar/);
}
isFooBar("Foo"); // ["Foo"]
isFooBar("Baz"); // null
So to clarify, I know the first example results in one compilation of the regex. But what about the second example?
Well, let's find out.
// http://stackoverflow.com/questions/3466850/complex-password-regular-expression
function isFooBar(str) {
return str.match(/^(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[##$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%^&+=]).*$)?$/);
}
console.time('1');isFooBar("Foo");console.timeEnd('1');
console.time('2');isFooBar("Bar");console.timeEnd('2');
(Open your console and run the code snippet above to see if the results for your browser.)
On Node.js 0.10.36 (V8 3.14.5.9):
1: 65ms
2: 0ms
On io.js 1.6.3 (V8 4.1.0.27):
1: 32ms
2: 0ms
So, I guess the answer to your question is YES, V8 is capable of automatically caching the regex.
EDIT:
Even though V8 is capable of such optimization, it might not in fact choose to always use this optimization. V8 has many complex heuristics for different cases, like when to inline a function, when to optimize a function, when to de-optimize a function, etc. Unless you are a V8 developer, many of these heuristics would appear to be bizarre or unexpected or both.
Not being a V8 developer myself, I do not know the answer to the specific question or if regexes are always automatically cached. However, even if I do know the answer, it may change in the future. So when you are writing code, I would still recommend storing the regex in such a way that it is clear what the intention for this variable is. And for the example above, this means lifting the regex variable out of the function isFooBar().
Another issue is how this regex is created. The example above and in OP's question are declared with a regular expression literal. However, if you are using the new RegExp() constructor, V8 would not be allowed to cache the regex since it might change during runtime.
http://code.google.com/p/v8/issues/detail?id=933#c3
In Chrome 9 we have removed a primitive caching of RegExp results. That means that we no longer take unrealistically low time for repeating the same operation on the same input over and over again.
The caching was originally added to make a point about benchmarks that were too simplistic (our own, at that time, included) being too easy to "game" by adding such caching (which makes no difference in real-world scenarios). Most benchmarks have since improved so much that we decided to remove the caching (and its unavoidable overhead).
The cache was added in v8 revision 4083 (released in Chrome 5) and removed in revision 5755 (will be in Chrome 9)
Is there a way to learn at how JavaScript is interpreted and executed? In .NET or JAVA for instance, you could look at the generated byte code, in C you could look at the generated assembly instruction but from what I gather, JavaScript is interpreted line by line and then it varies on the JS engine in different browsers.
Still is there a way to learn how JavaScript does this? Does the interpreter in modern browsers tend to look ahead and optimize as a compiler might?
For instance, if I did:
$('#div1').css('background-color','red');
$('#div1').css('color','white');
Could I have a perf gain by doing:
var x = $('#div1');
x.css('background-color','red');
x.css('color','white');
The point of this question is to get some information how one might gain some insight as to how JavaScript is run in the browser.
The optimization steps taken, as always, depend on the compiler. I know that SpiderMonkey is fairly well documented, open source, and I believe does JIT compilation. You can use it outside of the browser to tinker with, so that's one less black-box to deal with when experimenting. I'm not sure if there's any way to dump the compiled code as it runs to see how it optimizes in your code, but since there's no standard concept of an intermediate representation of Javascript (like there is with .NET/Java bytecode) it would be specific to the engine anyway.
EDIT: With some more research, it does seem that you can get SpiderMonkey to dump its bytecode. Note, however that optimizations can take place both in the interpreter that generates the bytecode and the JIT compiler that consumes/compiles/executes the bytecode, so you are only halfway there to understanding any optimizations that may occur (as is true with Java and .NET bytecodes).
V8 does some amazing things internally. It compiles to machine code and creates hidden classes for your objects. Mind-blowing details here: https://developers.google.com/v8/design
Ofcourse when it comes to the DOM, performing lookups can only go that fast. Which is why chaining or temp variables can make a difference, especially in loops and during animations.
Besides that, using the right selectors can be helpful. #id lookups are undoubtedly the fastest. Simple tagname or class lookups are reasonably fast as well. jQuery selectors like :not can't fall back on builtins and are considerably slower.
Besides reducing lookups, another good rule of thumb with the DOM is: If you need to do a lot of DOM manipulation, take out some parent node, do the manipulations, and reinsert it. This could save a whole lot of reflows/repaints.
Yes, you will get a performance gain. The DOM is not queried twice, and only one jQuery object is instantiated.
Yet you should not do this for performance (the gain will be negligible), but for code quality. Also, you do not need a variable, jQuery supports chaining:
$('#div1').css('background-color','red').css('color','white');
and the .css method also can take an object:
$('#div1').css({'background-color': 'red', 'color': 'white'});
I'm reading up a bit on using Strict Mode for JavaScript and it seems that, generally speaking, the idea is to force a more rigid set of rules onto the coder to ensure that the JS engine can optimise the code better. It almost feels like the JavaScript equivalent of "Option Explicit" in Visual Basic.
If this is basically the net effect of applying Strict Mode to my code, would the performance difference be such that it would be worth applying out of habit rather than case-by-case? Are there other advantages besides code stability that might be worth considering?
What are some of the key reasons I would want to apply Strict Mode to my scripts?
Well, strict mode code can certainly perform better because it removes issues that made optimization harder, for example, from the top of my head:
The with statement was removed (Really difficult -if not impossible- to optimize).
No more undeclared assignments, and other prohibitions, e.g. (delete varName;)
eval does not introduce variable/function declarations into the local scope.
arguments.callee was removed, (difficult to optimize (e.g. function inlining))
The arguments object index named properties are not anymore dynamically mapped to the named formal parameters.
I think the reasons to use it were spelled out well by John Resig, http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/, and it appears Firefox will be supporting it, http://whereswalden.com/2010/09/08/new-es5-strict-mode-support-now-with-poison-pills/, so it may be useful to look at, at least for libraries.
But, basically, it is to help prevent some common programming errors, but for some people losing the eval may be reason not to use it, and for me not having unnamed anonymous functions will be difficult, but, anything that can help reduce errors may be worthwhile.
I don't know if the performance would be worthy it, but I guess your results may vary. I suppose it depends on your script. But that doesn't mean to be the main point, but reducing your time in maintaining your code. So anything that makes save you time (and money) maintaining your code, and makes it faster, is golden.
I have been corrected, and, sadly, it doesn't include strong typing. Many years were spent by researchers to enforce typing to detect errors at compile time, and now we have to trust we are code is good, or verify it by hand or unit testing. IMHO, the time spent in unit testing is usually scarce in many places, and it should not be spent on things that could be done by the compiler.