skip to Main Content

I am working on a project and have been having some resources limitations issues.

I am fetching this JSon that contains a property with more than 2.0 MB of string, the idea is to work this string in order to present it inside a table.
However and mostly because of its size the browser isn’t able to process it, I have to reduce the bytesIndexTo variable in order for the loop to work.

// Fill an array with the available hexadecimal values for the left side of the table
let bytesIndexControl =  Array.from(Array(bytesIndexTo).keys()).map(i => 30 + i * 32);

var a = 1;
var hex = 1;

for (let i = bytesIndexFrom; i <= bytesIndexTo; i++) {

    // console.log(i + " - " + binary[i] + binary[a]);

    if (i === 0 )
        tableData = "<tr><th>0</th>";

    // Show hex value at the left side of the table
    if ( bytesIndexControl.includes(i - 2) ) {
        tableData += "<th>" + hex.toString(16)   + "</th>";
        hex++;
    }

    tableData += "<td>" + binary[i].toUpperCase() + binary[a].toUpperCase() + "</td>";

    if ( bytesIndexControl.includes(i) ) tableData += "</tr>";

    i++;
    a = a + 2;

}

I already made a PHP version of this code but the resources issues persist.

This is the current output

Endereço    00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F
0           DB  00  F2  F0  40  00  26  F0  08  00  84  00  72  FB  F6  F0
1           72  FB  F2  F0  40  00  42  F0  72  FB  9D  05  BE  88  E6  07
2           25  00  FA  00  D6  02  F2  02  00  FE  06  02  02  00  9A  88
(...)

Maybe running the code locally will work (Node.js) ?
Or is there a way to improve this loop ?

The goal is to inject this loop output on the DOM tree

Thanks,

3

Answers


  1. Chosen as BEST ANSWER

    Thanks for all the replies, I found this to be the best solution

    var a = 1;
    var hex = 1;
    
    const array = [];
    let index = 0;
    let index2 = 0;
    
    let indexX = 0;
    
    for (let i = bytesIndexFrom; i <= bytesIndexTo; i++) {
    
                if (i === 0 ) 
                    array.push("<tr>");
    
                // If index are different it's a different line
                if (index === index2 )  {
                    array.push("<th>" + hex.toString(16) + "</th>");
                    hex++;
                    index2++;
    
                    indexX = 0;
                }
                else
                    indexX++;
    
                array.push("<td title='" + index2 + " - " + indexXarray[indexX] + "'>" + binary[i].toUpperCase() + binary[a].toUpperCase() + "</td>");
    
                if (i === bytesIndexControl[index] )  {
                    array.push("</tr>");
                    index++;
                }
    
                i++;
                a = a + 2;
    
    }
    

    Instead of using arr.includes(obj) so search for the values inside an array I added some indexes in order to confirm if the data exists and matches the values, the code is more verbose but performs better.


  2. Try looping over one piece at a time:

    let bytesIndexTo = 1000; // This is just an arbitrary number
    for (let i = 0; i < binary.length; i++) {
      for (let j = i; j <= i + bytesIndexTo && j < binary.length; j++) {
        ... // Run your code
    
        i = j;
      }
    }
    

    I don’t have a large enough string to test that this works, but this should do the trick!

    Edit:

    How about instead try adding a sort of pagination where you only iterate

    through the max byte length times the current page number you are on.

    Example:

    let maxBytes = 1000;
    let currentPage = 3;
    let maxPage = Math.ceil(binary.length / maxBytes);
    
    if (currentPage > maxPage) {
      currentPage = maxPage;
    } else if (currentPage <= 0) {
      currentPage = 1;
    }
    
    for (let i = currentPage * maxBytes; i < (currentPage + 1) * maxBytes && i < binary.length; i++) {
        ... // Run your code
    }
    

    Now you can add buttons to add or subtract the current page number.

    Login or Signup to reply.
  3. The performance issue is about string is immutable in javascript.

    Each += operation creates copy of string and adding string to that copy.

    And pay attention that x += y is the same as x = x + y

    let string = '1MB string' // now memory is filled with 1MB
    
    string = string + '.' // same as +=, old string persisted, new created, now memory is filled with 2MB
    
    for (let i = 0; i < 100; i++)
      string += '.'
    
    // String length now is 1MB + 101 chars, memory is filled with > 100MB of previous versions of string, which will be garbage collected later.
    

    Do instead:

    const array = []
    // or
    const array = new Array(length) // if you can determine length
    
    for (let i = 0; i < 100; i++)
      array.push('string')
    
    const result = array.join('') // and no memory problems
    

    UPD benchmarks shows that join is slower, so it’s not for sure. Maybe with 2MB string join will be better

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search