Enhance the efficiency of recurrent actions in QScriptEngine

I am currently working on optimizing the operations of QScriptEngine within one of my functions.

The function, called executeCustomJSOperation, is responsible for executing the same JS code across multiple files. Each file requires a modification to a global variable called $xmlData. Essentially, this function loads an XML file into memory using the $xmlData variable and then applies the same JavaScript code (jsString) to edit the XML file using JavaScript. Finally, the $xmlData variable is updated with the edited XML content.

I managed to achieve a 2.5 speedup by implementing an OpenMP parallel for loop over the XML files processing. However, I am now looking for ways to further enhance the speed of this function.

Below is the code snippet:

// This function allows users to echo JavaScript variables for debugging purposes through cout
QScriptValue echo(QScriptContext *context, QScriptEngine *engine)
{
    std::cout << context->argument(0).toString().toUtf8().constData() << std::endl; 
    return "";
}

void executeCustomJSOperation(const QString &jsString, const QStringList &filesToProcess){  
    QString rexmlString, jsxmlString;
    QFile rexmlfile(":/resources/libs/rexml.js"); // loading JavaScript libraries as strings into memory
    QFile jsxmlfile(":/resources/libs/jsxml.js");

    rexmlfile.open(QFile::ReadOnly | QFile::Text);
    jsxmlfile.open(QFile::ReadOnly | QFile::Text);

    rexmlString=QTextStream(&rexmlfile).readAll();
    jsxmlString=QTextStream(&jsxmlfile).readAll();

    // Processing all XmlFiles
#pragma omp parallel for // Achieved 2.5 speedup on my machine
    for(int i=0; i<filesToProcess.size(); i++){

        QString currXmlFileString;

        QScriptEngine engine;
        QScriptValue engineResult;

        // Adding echo function for user debugging
        QScriptValue echoFunction = engine.newFunction(echo);
        engine.globalObject().setProperty("echo", echoFunction);

        engine.evaluate(rexmlString); // Loading JavaScript libraries in the JS engine
        engine.evaluate(jsxmlString);

        QFile currXmlFile(filesToProcess[i]);

        currXmlFileString=QTextStream(&currXmlFile).readAll();

        currXmlFile.close(); 

        engine.globalObject().setProperty("$xmlData",currXmlFileString);

        engine.evaluate("main(); function main() {"+jsString+"}"); // The main function allows the use of 'return' statement to exit from user code

        engineResult=engine.globalObject().property("$xmlData");

        QTextStream(&currXmlFile) << engineResult.toString(); // Retrieving modified XML by JavaScript and saving it back to the file
    }
}

Are there any suggestions on how to further optimize this code? Feel free to ask if you have any questions.

Answer №1

Is there a reason for initializing a new QScriptEngine in every iteration? It might be better to move the script evaluation outside of the loop.

engine.evaluate(jsxmlString);

This could pose challenges with threading, as you may need to organize multiple threads and have one script engine per thread rather than per file. Starting with a single-threaded approach could help gauge potential speed improvements before complicating things.

If your JavaScript code is truly meant for one-time use, consider optimizing with QScriptProgram. In this case, setting up a set number of worker threads with their own QScriptProgram (and one QScriptEngine per iteration) like in your current implementation may be necessary.

Answer №2

To optimize execution speed, consider creating a QScriptProgram to contain all JS code and then evaluate it using QScriptEngine::evaluate. This approach can eliminate the need to parse JS code repeatedly, resulting in faster processing. However, it's important to note that QScriptProgram is not officially recognized as reentrant or thread-safe. As a result, there may be uncertainty regarding its functionality when used concurrently in multiple threads, even if each thread has its own QScriptProgram object.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Node JS Request Params 500 Error

When generating the URI, everything appears to be in order and the list data is displayed on the page. However, when sending the request in the request method, a 500 error occurs instead of the body being returned. Here is the URI: http://yufluyuinnepal.c ...

Continuous polling with Ajax in Rails does not trigger the display of an alert box

Trying to implement ajax polling using the RailsCast tutorial on ajax polling (#229) but encountering an issue where the alert box doesn't pop up after running the server. Here's the code in app/views/quotes/index.js.erb: alert('Hey') ...

The active class in the navbar is malfunctioning in Bootstrap 4

I've been searching high and low to figure out how to add an active class to the current open link in my navbar. I've scoured Google and Stack Overflow for answers, but everything I found only applies to hash-type navbars using href="#". None of ...

Can one verify if an Angular application currently has active app modules running?

I am developing a unique plugin for Angular that is designed to automatically initialize an Angular app module if none are found. However, if there is already a running or declared ng-app, my plugin will utilize that existing module instead. Here is an i ...

What is the best way to divide a string into an array containing both linked and non-linked elements?

I'm struggling to find the right solution to my problem. I need to create a view that is enclosed in a clickable div. The content will consist of plain text mixed with clickable URLs - the issue arises when clicking on a link also triggers the method ...

Top replacements for jQuery in AngularJS applications

It would be great to compile a comprehensive list of jQuery alternatives that are compatible with AngularJS, capable of manipulating styles (css), and supporting effects like fadeIn, fadeOut, slideDown, slideUp, etc. Based on feedback from comments, we sh ...

How can I convert a MongoDB document into a DTO in NestJS?

I'm currently working with a data layer that interacts with a MongoDB database. My goal is to only handle MongoDB documents in this layer without exposing the implementation details to my services. My current approach involves the following code: // ...

Issue with nextElementSibling not applying CSS style

My current issue revolves around a button that is designed to open or close a collapsible div. The HTML structure of this element looks like the following: <div class='outer-collapsible'> <button type='button' class='col ...

What could be causing my code to generate an error?

I'm encountering an error in module.js:339 where it throws an 'err' and I'm struggling to identify the exact cause or line of code that needs fixing. Any guidance on where to look would be greatly appreciated, as I seem to be searching ...

What is the best way to retrieve an ID from a select multiple using Element?

I am working on a select element for assigning persons to a project. My goal is to send the ID of the selected person object to a specific function. Here is what I have tried so far: <el-form-item label="Assign to:" prop="person"> & ...

Using Async functions with Node.js Express.js router

I've been trying to search on Google, but I can't seem to find a clear answer to this one... Is it possible to pass ES7 async functions to the Express router? For example: var express = require('express'); var app = express(); app.ge ...

What is the best way to capture dynamic import errors in JavaScript?

I am currently developing a website using Next.js. My goal is to utilize dynamic import import() to load a module dynamically, even if it may not exist. If the module does not exist, I am fine with suppressing it: const Blog = async () => { let L ...

Adjust the height of the element to prevent the need for a double-scroll

Currently, I have created a webpage for a client that includes a PDF using an iframe tag. The issue arises when the PDF is rather large, resulting in two scrollbars - one for the page and one for the embedded PDF within the iframe (loaded through the integ ...

In React Router, redirect when location.state is not defined

import React, { useState } from "react"; import { Redirect } from "react-router-dom"; function Update(data) { if(!data.location.state) return <Redirect to="/"/> const [name, setName] = useState(dat ...

Integrating new information into an existing JSON file using React Native

Currently, I am attempting to input new data into an existing JSON file using text input. In my project using React Native, I have a JSON file named PartyInfo.json where certain data is stored. The goal is to have this data passed from a form and saved in ...

Combining two unchangeable objects in JavaScript: A guide

Currently, I'm working on a project using React and Formik. In my validation file, I have exported two validation schema named as `facValidation` and `insValidation`. Here is the content of my `validation.js` file: export const facValidation = Yup.o ...

Execute an asynchronous request using Javascript to communicate with a Spring Controller

I've created a JSP page that includes some JavaScript code: function sendData(tableID) { var table = document.getElementById(tableID); var dataArray= new Array(); for (var i = 1;i<table.rows.length; i++){ var row = table. ...

How to pass parameters while updating parent values in VueJS using emit?

Explaining my dilemma with uploading images: In my form, users can upload images using the following code snippet: <input id="visualisation_upload" @change="onThumbnailChanged" name="visualisation_upload" accept="imag ...

Could you provide me with a demonstration of cross-domain functionality?

Similar Inquiry: Methods to bypass the same-origin policy Let's consider two domains for this example - "" and "". The first domain "" is generating data in JSON format as shown below: { "str_info": [ { "str_name": "Mark ...

Enhancing functionality by updating a function to accept an object as input instead of individual key:value pairs in TypeScript

I'm currently tackling a challenge with a friend's icon library component, specifically with their set() function. The issue arises when I want to invoke two functions, namely setRandomColor() and setColor(), both intended to update two values w ...