java 8 nashorn engine is really slow - javascript

I am running the following javascript test
var mark = java.lang.System.nanoTime() / 1000000000.0;
for(var i = 0; i != 1000; i++) {
}
var now = java.lang.System.nanoTime() / 1000000000.0;
var e = now - mark;
print(1 / e);
and get this result
27.361456496425802
this seems really slow almost a bug or something i am doing wrong. Here is the java code
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
String[] lines = IO.readAllLines(IO.file(root, "LoadList.txt"));
String script = "";
for(int i = 0; i != lines.length; i++) {
String file = lines[i].trim();
if(!file.startsWith("#") && file.length() != 0) {
script += IO.readAllText(IO.file(root, file));
}
}
engine.eval(script);
} catch(Exception ex) {
ex.printStackTrace();
}
does anybody know what i am doing wrong or have seen this type of problem and know how to fix if?
Thanks in advance

after doing some research it appears that java's javascript takes a little while to warm up to speed. here is an update to the test
for(var i = 0; i != 1000; i++) {
var mark = java.lang.System.nanoTime() / 1000000000.0;
for(var j = 0; j != 1000; j++) {
}
var now = java.lang.System.nanoTime() / 1000000000.0;
var e = now - mark;
print(1 / e + " fps")
}
and by the last iteration i get 99108.03064699778 fps. (it does vary the lowest one i got, on the last iteration, was around 50000 fps)

Related

Emscripten OOB Exception within C from Javascript

I'm trying to pass an array of strings from JS to C using Emscripten. I pass my array to C but when I try to deference, it does not work, it raises "index out of bounds". I've tried many different things so I'll post the minimal amount of code that can reproduce the issue (at least on my machine!). I'm sure I missed something...
Basically trying to put a string into an array (of strings) and give that to C for printing (I'm doing other stuff of course). Feel free to change the "gmp_" or "mpz_" to your (that's not the problem).
Javascript:
var nbData = 1;
var nbColPerData = 1;
var data = new Uint32Array(nbColPerData);
data[0] = this.i2wasm(this.mod);
var nBytes = data.length * data.BYTES_PER_ELEMENT;
var dataPtr = Module._malloc(nBytes);
var dataHeap = new Uint8Array(Module.HEAP8.buffer,dataPtr,nBytes);
dataHeap.set(new Uint8Array(data.buffer));
// create array of pointers
var pointers = new Uint32Array(nbData);
for (var i =0; i < pointers.length; i++) {
pointers[i] = dataPtr + i * data.BYTES_PER_ELEMENT;
console.log("pointers["+i+"] = " + pointers[i].toString(16));
}
// create pointer array on the heap
var nPointerBytes= pointers.length * pointers.BYTES_PER_ELEMENT;
var pointerPtr = Module._malloc(nPointerBytes);
var pointerHeap = new Uint8Array(Module.HEAP8.buffer, pointerPtr,nPointerBytes);
pointerHeap.set( new Uint8Array(pointers.buffer));
printIntMatrix(pointerHeap,nbData)
Module._free(pointerHeap.byteOffset);
Module._free(dataHeap.byteOffset);
i2wasm (hexadecimal string to int array for wasm, works properly):
return allocate(intArrayFromString(integer),'i8',ALLOC_NORMAL);
C code:
void EMSCRIPTEN_KEEPALIVE printInt(char *hex) {
mpz_t n;
mpz_init(n);
printf("printing INT at %p\n",hex);
/////////////////////////////////////
// HERE IT PANICS !
/////////////////////////////////////
printf("printing INT value: %c\n",*hex);
if (mpz_set_str(n,hex,16) != 0) {
printf("hexadecimal invalid");
return;
}
gmp_printf("printInt: %Zd\n",n);
mpz_clear(n);
}
void EMSCRIPTEN_KEEPALIVE printIntMatrix(char **mat, int n) {
printf("printIntMatrix !!\n");
for(int i = 0; i < n; i++) {
printf("matrix[%d] => \n",i);
printf("matrix[%d] => %p\n",i,mat[i]);
printInt(mat[i]);
printf("matrix[%d] => %p DONE\n",i,mat[i]);
}
}
i2wasm() returns char*, so dataPtr is char**.
And _printIntMatrix(pointerHeap, nbData) means _printIntMatrix(pointerHeap | 0, nbData), eventually it is _printIntMatrix(NULL, nbData).
So if printIntMatrix doesn't need char ***mat, _printIntMatrix(dataPtr, nbData); would work.

Random post widget script not working on blogger

I'm trying do make a random post widget to work on my blog (blogger), but the browser keeps giving me an error saying that the script is unresponsive:
"A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.
Script: http://testeshoon.blogspot.pt/:4792"
The script came with the template.
Have tried other scripts from the web but they all do the same.
I'm trying to solve this for the past 2 days, but can't figure out what the problem is.
Can anyone help me?
Really need this to work, at least, in 2 widgets.
Tried scripts for recent posts and those work just fine, but the ones for random doesn't.
<ul id='random-posts'>
<script type='text/javaScript'>
var rdp_numposts = 2;
var rdp_snippet_length = 100;
var rdp_info = 'yes';
var rdp_comment = 'Comments';
var rdp_disable = 'Comments Disabled';
var rdp_current = [];
var rdp_total_posts = 0;
var rdp_current = new Array(rdp_numposts);
function totalposts(json) {
rdp_total_posts = json.feed.openSearch$totalResults.$t
}
document.write('<script type=\"text/javascript\" src=\"/feeds/posts/default/-/noticias?alt=json-in-script&max-results=0&callback=totalposts\"><\/script>');
function getvalue() {
for (var i = 0; i < rdp_numposts; i++) {
var found = false;
var rndValue = get_random();
for (var j = 0; j < rdp_current.length; j++) {
if (rdp_current[j] == rndValue) {
found = true;
break
}
};
if (found) {
i--
} else {
rdp_current[i] = rndValue
}
}
};
function get_random() {
var ranNum = 1 + Math.round(Math.random() * (rdp_total_posts - 1));
return ranNum
};
</script>
<script type='text/javaScript'>
var _0x3eb4=["\x65\x6E\x74\x72\x79","\x66\x65\x65\x64","\x24\x74","\x74\x69\x74\x6C\x65","\x63\x6F\x6E\x74\x65\x6E\x74","\x73\x75\x6D\x6D\x61\x72\x79","","\x72\x65\x70\x6C\x61\x63\x65","\x6C\x65\x6E\x67\x74\x68","\x73\x75\x62\x73\x74\x72\x69\x6E\x67","\x20","\x6C\x61\x73\x74\x49\x6E\x64\x65\x78\x4F\x66","\x26\x23\x31\x33\x33\x3B","\x6C\x69\x6E\x6B","\x74\x68\x72\x24\x74\x6F\x74\x61\x6C","\x72\x65\x6C","\x61\x6C\x74\x65\x72\x6E\x61\x74\x65","\x68\x72\x65\x66","\x70\x75\x62\x6C\x69\x73\x68\x65\x64","\x6D\x65\x64\x69\x61\x24\x74\x68\x75\x6D\x62\x6E\x61\x69\x6C","\x75\x72\x6C","\x68\x74\x74\x70\x3A\x2F\x2F\x33\x2E\x62\x70\x2E\x62\x6C\x6F\x67\x73\x70\x6F\x74\x2E\x63\x6F\x6D\x2F\x2D\x35\x53\x6F\x56\x65\x31\x4B\x36\x4A\x53\x6B\x2F\x55\x74\x6C\x30\x4F\x4F\x6D\x75\x63\x41\x49\x2F\x41\x41\x41\x41\x41\x41\x41\x41\x46\x36\x45\x2F\x68\x51\x67\x68\x67\x44\x5F\x45\x4A\x64\x51\x2F\x73\x31\x36\x30\x30\x2F\x6E\x6F\x5F\x74\x68\x75\x6D\x62\x2E\x70\x6E\x67","\x3C\x6C\x69\x3E","\x77\x72\x69\x74\x65","\x3C\x61\x20\x68\x72\x65\x66\x3D\x22","\x22\x20\x72\x65\x6C\x3D\x22\x6E\x6F\x66\x6F\x6C\x6C\x6F\x77\x22\x3E\x3C\x69\x6D\x67\x20\x61\x6C\x74\x3D\x22","\x22\x20\x73\x72\x63\x3D\x22","\x22\x2F\x3E\x3C\x2F\x61\x3E","\x3C\x64\x69\x76\x3E\x3C\x61\x20\x68\x72\x65\x66\x3D\x22","\x22\x20\x72\x65\x6C\x3D\x22\x6E\x6F\x66\x6F\x6C\x6C\x6F\x77\x22\x20\x74\x69\x74\x6C\x65\x3D\x22","\x22\x3E","\x3C\x2F\x61\x3E\x3C\x2F\x64\x69\x76\x3E","\x79\x65\x73","\x3C\x73\x70\x61\x6E\x3E\x3C\x64\x69\x76\x20\x20\x63\x6C\x61\x73\x73\x3D\x22\x72\x70\x2D\x69\x6E\x66\x6F\x22\x3E","\x2F","\x20\x2D\x20","\x3C\x2F\x64\x69\x76\x3E\x3C\x2F\x73\x70\x61\x6E\x3E","\x3C\x62\x72\x2F\x3E\x3C\x64\x69\x76\x20\x63\x6C\x61\x73\x73\x3D\x22\x72\x70\x2D\x73\x6E\x69\x70\x70\x65\x74\x22\x3E","\x3C\x2F\x64\x69\x76\x3E\x3C\x64\x69\x76\x20\x73\x74\x79\x6C\x65\x3D\x22\x63\x6C\x65\x61\x72\x3A\x62\x6F\x74\x68\x22\x3E\x3C\x2F\x64\x69\x76\x3E\x3C\x2F\x6C\x69\x3E","\x3C\x73\x63\x72\x69\x70\x74\x20\x74\x79\x70\x65\x3D\x22\x74\x65\x78\x74\x2F\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x22\x20\x73\x72\x63\x3D\x22\x2F\x66\x65\x65\x64\x73\x2F\x70\x6F\x73\x74\x73\x2F\x64\x65\x66\x61\x75\x6C\x74\x3F\x61\x6C\x74\x3D\x6A\x73\x6F\x6E\x2D\x69\x6E\x2D\x73\x63\x72\x69\x70\x74\x26\x73\x74\x61\x72\x74\x2D\x69\x6E\x64\x65\x78\x3D","\x26\x6D\x61\x78\x2D\x72\x65\x73\x75\x6C\x74\x73\x3D\x31\x26\x63\x61\x6C\x6C\x62\x61\x63\x6B\x3D\x72\x61\x6E\x64\x6F\x6D\x5F\x70\x6F\x73\x74\x73\x22\x3E\x3C\x2F\x73\x63\x72\x69\x70\x74\x3E"];function random_posts(_0x2f3cx2){for(var i=0;i<rdp_numposts;i++){var _0x2f3cx4=_0x2f3cx2[_0x3eb4[1]][_0x3eb4[0]][i];var _0x2f3cx5=_0x2f3cx4[_0x3eb4[3]][_0x3eb4[2]];if(_0x3eb4[4] in _0x2f3cx4){var _0x2f3cx6=_0x2f3cx4[_0x3eb4[4]][_0x3eb4[2]];} else {if(_0x3eb4[5] in _0x2f3cx4){var _0x2f3cx6=_0x2f3cx4[_0x3eb4[5]][_0x3eb4[2]];} else {var _0x2f3cx6=_0x3eb4[6];} ;} ;_0x2f3cx6=_0x2f3cx6[_0x3eb4[7]](/<[^>]*>/g,_0x3eb4[6]);if(_0x2f3cx6[_0x3eb4[8]]<rdp_snippet_length){var _0x2f3cx7=_0x2f3cx6;} else {_0x2f3cx6=_0x2f3cx6[_0x3eb4[9]](0,rdp_snippet_length);var _0x2f3cx8=_0x2f3cx6[_0x3eb4[11]](_0x3eb4[10]);_0x2f3cx7=_0x2f3cx6[_0x3eb4[9]](0,_0x2f3cx8)+_0x3eb4[12];} ;for(var _0x2f3cx9=0;_0x2f3cx9<_0x2f3cx4[_0x3eb4[13]][_0x3eb4[8]];_0x2f3cx9++){if(_0x3eb4[14] in _0x2f3cx4){var _0x2f3cxa=_0x2f3cx4[_0x3eb4[14]][_0x3eb4[2]]+_0x3eb4[10]+rdp_comment;} else {_0x2f3cxa=rdp_disable;} ;if(_0x2f3cx4[_0x3eb4[13]][_0x2f3cx9][_0x3eb4[15]]==_0x3eb4[16]){var _0x2f3cxb=_0x2f3cx4[_0x3eb4[13]][_0x2f3cx9][_0x3eb4[17]];var _0x2f3cxc=_0x2f3cx4[_0x3eb4[18]][_0x3eb4[2]];if(_0x3eb4[19] in _0x2f3cx4){var _0x2f3cxd=_0x2f3cx4[_0x3eb4[19]][_0x3eb4[20]];} else {_0x2f3cxd=_0x3eb4[21];} ;} ;} ;document[_0x3eb4[23]](_0x3eb4[22]);document[_0x3eb4[23]](_0x3eb4[24]+_0x2f3cxb+_0x3eb4[25]+_0x2f3cx5+_0x3eb4[26]+_0x2f3cxd+_0x3eb4[27]);document[_0x3eb4[23]](_0x3eb4[28]+_0x2f3cxb+_0x3eb4[29]+_0x2f3cx7+_0x3eb4[30]+_0x2f3cx5+_0x3eb4[31]);if(rdp_info==_0x3eb4[32]){document[_0x3eb4[23]](_0x3eb4[33]+_0x2f3cxc[_0x3eb4[9]](8,10)+_0x3eb4[34]+_0x2f3cxc[_0x3eb4[9]](5,7)+_0x3eb4[34]+_0x2f3cxc[_0x3eb4[9]](0,4)+_0x3eb4[35]+_0x2f3cxa)+_0x3eb4[36];} ;document[_0x3eb4[23]](_0x3eb4[37]+_0x2f3cx7+_0x3eb4[38]);} ;} ;getvalue();for(var i=0;i<rdp_numposts;i++){document[_0x3eb4[23]](_0x3eb4[39]+rdp_current[i]+_0x3eb4[40]);} ;
</script>
</ul>
Let's suppose that you want k distinct numbers (random post indexes) from n possible numbers. Here is an implementation
function getRandomSubset(n, k) {
if (k > n) {
//impossible
return;
}
//initializing the result set as empty
var output = [];
//creating a variable
var input;
//we need k distinct random numbers
while (k-- > 0) {
//we get a random integer, 0 <= input < n
input = Math.floor(Math.random() * n);
//if it is duplicated, increment it inside the n'th modulo class until a new value is found
while (output.indexOf(input) >= 0) {
input = (input + 1) % n;
}
//store the new distinct value into the results
output[output.length] = input;
}
return output;
}
There are many other possible ways.

Try to implement a simple text parser in javascript

i´m trying to bring a simple text parser from Java to Javascript.
The requierement is to transform a given csv file in to another format. The original file list a number of values according to one id in certain lines:
for example:
11111; 12; 23; 23 ;....
11111; 32; 12; 12 ;....
So the first value is an Id and the other values are according to this Id.
Now I need the same file with alle the values according to the one Id in a single line.
the result should be something like:
11111;12; 23; 23; 32; 12; 12 ;....
I already achieved this with a simple Java class:
public static void main(String[] args) throws Exception {
PrintWriter writer = new PrintWriter("t2_lines.csv", "UTF-8");
BufferedReader br = new BufferedReader(new FileReader("t2.csv"));
String previousId="";
String line;
while ((line = br.readLine()) != null) {
String [] words = line.split(";");
String id = words[0];
if (previousId.equals(id)){
// the loop starts at 4 to cut out some unneded values
for(int i=4;i<words.length;i++) {
writer.print(words[i]+";");
}
}else{
writer.println("");
for(String word : words)
writer.print(word+";");
previousId = id;
}
}
br.close();
writer.close();
}
and now I try to rebuild this thing in Javascript by read in a file from the client and present the result in a textfield - but unfortunately i´ve never implemented anything in Javascript before...
This is my approach so far:
window.onload = function () {
var fileInput = document.getElementById('fileInput');
var origFileDisplayArea = document.getElementById('origFileDisplayArea');
var reformatFileDisplayArea= document.getElementById('reformatFileDisplayArea');
fileInput.addEventListener('change', function (e) {
var file = fileInput.files[0];
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function (e) {
var result = reader.result;
var table = parse(result);
origFileDisplayArea.innerText = table;
}
} else {
origFileDisplayArea.innerText = "File not supported!"
}
});
}
function parse(input) {
var previousId = "";
var table = "";
if (typeof input !== "undefined")
var lines = input.split("\n");
for (var i = 0; i <= lines.length; i++) {
var line = lines[i];
if (typeof line !== "undefined")
var words = line.split(";");
console.log("words length: ", words.length);
for (var j = 0; j <= words.length; j++ ) {
var word = words[j];
if (typeof word !== "undefined") {
word.toString();
var id = words[0];
if (previousId === id) {
for (var jj = 4; jj <=words.length; jj++){
console.log("jj: " + jj)
table += words[jj]+";";
}
}else {
table += "\n";
for (var word in words) {
table += word + ";";
previousId = id;
}
}
}
}
}
return table;
}
But unfortunately i´m stucked now with undefined values and the whole thing took ages to run.
So any hints/help would be greatly appreciated.
Thanks in advance
Yes for the FileReader, I can't see a way to avoid that in this context. That doesn't look like where you have the problem.
As for parse, the split method can use up a lot of memory so I'd avoid using it on the whole file, and for..in is not designed for looping over an Array.
function parse(str_in) {
var i = -1, j = -1,
str_out = '',
last_id = '',
words;
str_in += '\n'; // not sure if necessary - let the last line pass `while`
// loop by seeking out the next new line
// i = old_index + 1
// j = next \n after old_index
// .slice(i, j) gives just the line
while (-1 !== (j = str_in.indexOf('\n', i = j + 1))) {
words = str_in.slice(i, j).split(';')
// loop words to trim whitespace here if you want
if (last_id === words[0]) // throw away first item if on the same id
words = words.slice(1);
else {
last_id = words[0];
if (str_out.length) // lazy prevent first char newline
str_out += '\n';
}
str_out += words.join(';'); // if you trimmed witespace, re-add here
// if you don't have a final semicolon, add it too
}
return str_out;
}
Now
parse('11111; 12; 23; 23 ;\n11111; 32; 12; 12 ;');
// "11111; 12; 23; 23 ; 32; 12; 12 ;"
Alternatively, you might find it easier to write methods similar to what you're used to in Java so you can work with minimal changes, e.g.
function ReadLineGenerator(text) {
var start = -1, end = -1;
return function readLine() {
if (end < start) {
start = end = -1;
return null;
}
start = end + 1;
end = text.indexOf('\n', start);
if (end !== -1)
return text.slice(start, end);
else
return text.slice(start);
};
}
// example usage
var str = 'a\nb\nc',
f = ReadLineGenerator(str),
line;
while (null !== (line = f()))
console.log(line);
// "a", "b", "c" logged
// line === null

Why is a custom array reverse implementation twice as fast versus .reverse() in V8

A simple implementation for reversing an array is twice as fast compared to the built in function in Javascript, when tested in Chrome. What's V8 doing? Here is the test:
var newArr = [];
var newArrDefault = [];
for(var i = 0; i < 10000000; i++){
newArr[i] = i;
newArrDefault[i] = i;
}
var startDefault = new Date();
newArrDefault.reverse();
console.log("Built in method took " + (new Date().getTime() - startDefault.getTime()));
var start = new Date();
for(var i = 0; i < newArr.length / 2; i++){
var tmp = newArr[i];
newArr[i] = newArr[newArr.length-i-1];
newArr[newArr.length-i-1] = tmp;
}
console.log("Custom method took " + (new Date().getTime() - start.getTime()));
Results on Version 20.0.1132.47 Ubuntu 12.04 (144678):
Built in method took 149
Custom method took 71
For the fun of it, I implemented the specification like so:
var upper, upperExists, lowerExists, lowerValue, upperValue;
for(var lower = 0, len = newArr.length >>> 0, middle = Math.floor(len / 2); lower != middle; ++lower) {
upper = len - lower - 1;
lowerValue = newArr[lower];
upperValue = newArr[upper];
lowerExists = newArr.hasOwnProperty(lower);
upperExists = newArr.hasOwnProperty(upper);
if (lowerExists && upperExists) {
newArr[lower] = upperValue;
newArr[upper] = lowerValue;
} else if (upperExists) {
newArr[lower] = upperValue;
delete newArr[upper];
} else if (lowerExists) {
newArr[upper] = lowerValue;
delete newArr[lower];
}
}
The jsperf can be found here.
It includes a whole bunch of code to deal with missing entries, which is why it's so much slower than both the native and your code (some optimizations may be possible, but it won't affect the performance enough). The performance difference between your code and the native implementation wasn't very conclusive though.
Under most circumstances arrays are a contiguous block of values with no gaps in between, so you should be safe with that kind of code; as long as you know the difference :)

Objective-C vs JavaScript loop performance

I have a PhoneGap mobile application that I need to generate an array of match combinations. In JavaScript side, the code hanged pretty soon when the array of which the combinations are generated from got a bit bigger. So, I thought I'll make a plugin to generate the combinations, passing the array of javascript objects to native side and loop it there.
To my surprise the following codes executes in 150 ms (JavaScript) whereas in native side (Objective-C) it takes ~1000 ms.
Does anyone know any tips for speeding up those executing times? When players exceeds 10, i.e. the length of the array of teams equals 252 it really gets slow. Those execution times mentioned above are for 10 players / 252 teams.
Here's the JavaScript code:
for (i = 0; i < GAME.teams.length; i += 1) {
for (j = i + 1; j < GAME.teams.length; j += 1) {
t1 = GAME.teams[i];
t2 = GAME.teams[j];
if ((t1.mask & t2.mask) === 0) {
GAME.matches.push({
Team1: t1,
Team2: t2
});
}
}
}
... and here's the native code:
NSArray *teams = [[NSArray alloc] initWithArray: [options objectForKey:#"teams"]];
NSMutableArray *t = [[NSMutableArray alloc] init];
int mask_t1;
int mask_t2;
for (NSInteger i = 0; i < [teams count]; i++) {
for (NSInteger j = i + 1; j < [teams count]; j++) {
mask_t1 = [[[teams objectAtIndex:i] objectForKey:#"mask"] intValue];
mask_t2 = [[[teams objectAtIndex:j] objectForKey:#"mask"] intValue];
if ((mask_t1 & mask_t2) == 0) {
[t insertObject:[teams objectAtIndex:i] atIndex:0];
[t insertObject:[teams objectAtIndex:j] atIndex:1];
/*
NSArray *newCombination = [[NSArray alloc] initWithObjects:
[teams objectAtIndex:i],
[teams objectAtIndex:j],
nil];
*/
[combinations addObject:t];
}
}
}
... the array in question (GAME.teams) looks like this:
{
count = 2;
full = 1;
list = (
{
index = 0;
mask = 1;
name = A;
score = 0;
},
{
index = 1;
mask = 2;
name = B;
score = 0;
}
);
mask = 3;
name = A;
},
{
count = 2;
full = 1;
list = (
{
index = 0;
mask = 1;
name = A;
score = 0;
},
{
index = 2;
mask = 4;
name = C;
score = 0;
}
);
mask = 5;
name = A;
},
Generally when you have a performance problem, you should profile your app using the Time Profiler instrument.
In this case, I can see some likely problems.
First of all, you're doing this in your inner loop:
[t insertObject:[teams objectAtIndex:i] atIndex:0];
[t insertObject:[teams objectAtIndex:j] atIndex:1];
You're just inserting more and more objects at the beginning of your t object. You're never emptying it out. I'm pretty sure that's not what you want, and it's probably a performance problem too.
Second, you're sending a lot of messages unnecessarily. For example, you're extracting masks O(N2) times. You can optimize this by extracting all of the masks once.
NSArray *teams = [options objectForKey:#"teams"];
NSUInteger teamCount = teams.count;
int masks[teamCount];
for (NSUInteger i = 0; i < teamCount; ++i) {
masks[i] = [[teams[i] objectForKey:#"mask"] intValue];
}
NSMutableArray *matches = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < teamCount; ++i) {
for (NSUInteger j = i + 1; j < teamCount; ++j) {
if ((masks[i] & masks[j]) == 0) {
[matches addObject:#[teams[i], teams[j]]];
}
}
}
You're still doing O(N2) iterations, but you're doing a lot less work on each iteration.
One thing to note is that
[t insertObject:[teams objectAtIndex:i] atIndex:0];
causes all of the elements in t to be shifted each time it is used. That could significantly slow things down since you're doing that twice in a loop. It's probably better to use [t addObject: ...].
Also, the NSMutableArray may be getting resized unnecessarily. If you know roughly how large it will need to be, you can initialize it with a specific capacity:
NSMutableArray *t = [[NSMutableArray alloc] initWithCapacity: size];

Categories

Resources