首页 > 解决方案 > 通过多处理/并行编程提高蛮力节点脚本的性能

问题描述

我有 5 个单词列表。让我们称他们为list1, list2, list3, list4, list5
有一个包含 2048 个单词的单词超集。
每个列表都包含来自单词超集的全部或部分单词。

例子:
superset = ['one', 'two', 'three', 'a', 'b', 'c', 'd', 'e', 'f', 'h', 'i', 'j', 'k', 'g', 'z', 'blie']
list1 = ['one', 'two', 'three'];
list2 = ['a', 'b', 'c'];
list3 = ['d', 'e', 'f'];
list4 = ['g'];
list5 = ['h', 'i', 'j', 'k'];

最终的字符串res是通过连接每个列表中的一个单词来生成的。例如:'one' + 'b' + 'f' + 'g' + 'k' = 'onebfgk

我有一个解码功能,它接收res并输出一个数字。我有兴趣找到解码为给定数字的字符串:prize

目前,我正在生成所有可能的组合res,对其进行解码并将其与给定的prize.
我当前的 node.js 脚本如下所示:

var prize = 1234;
var list1 = ['one', 'two', 'three'];
var list2 = ['a', 'b', 'c'];
var list3 = ['d', 'e', 'f'];
var list4 = ['g'];
var list5 = ['h', 'i', 'j', 'k'];
var word1 = '';
var word2 = '';
var word3 = '';
var word4 = '';
var word5 = '';

for (var n = 0; n < list1.length; n++) {
    word1 = list1[n];
    for (var m = 0; m < list2.length; m++) {
        word2 = list2[m];
        for (var o = 0; o < list3.length; o++) {
            word3 = list3[o];
            for (var p = 0; p < list4.length; p++) {
                word4 = list4[p];
                for (var q = 0; q < list5.length; q++) {
                    word5 = list5[q];
                    let res = word1 + word2 + word3 + word4 + word5;
                    if (decode(res) == prize){
                        console.log(res);
                        throw new Error("Found the match. The program will now exit");
                    }
                }
            }
        }
    }
}

我有兴趣加快速度。我如何修改脚本以通过使用 GPU 或多处理/并行处理或任何其他方式来大幅加快它的速度?

我仅限于使用 node.js,因为解码功能来自节点模块。

标签: node.jsmultiprocessingbrute-force

解决方案


NodeJS 实际上是用 C++ 编写的,所以如果你想执行一些资源密集型工作,我建议你使用NodeJS 插件功能。这是我发现在 NodeJS 中优化一些需要蛮力算法的代码的最佳方法。

在我的一些项目中,我自己遵循了一些关于该主题的出色教程:

它显然需要您了解一些 C++,但我认为没有更好的方法,因为您的目标是纯粹的优化和多线程操作的潜力。

C++ 代码的第一种方法是:

#include <iostream>
#include <string>

using namespace std;

bool compare(string _str,int seed){
    int val = 0;
    //Generate an int with the string AKA your decode() function
    for(int i = 0; i<sizeof(_str)/sizeof(_str[0]);i++){
            int letter = _str[i];
            val+= letter;
        }
    //Compare the result
    if(val == seed){
            return true;
        }else{
            return false;
        }
    }

int main()
{
    int prize = 753; //For twoadgk
    string list1[3] = {"one", "two", "three"};
    char list2[3] = {'a', 'b', 'c'};
    char list3[3] = {'d', 'e', 'f'};
    char list4[1] = {'g'};
    char list5[4] = {'h', 'i', 'j', 'k'};
    string word1 = "";
    string word2 = "";
    string word3 = "";
    string word4 = "";
    string word5 = "";
        
    for (int n = 0; n < sizeof(list1)/sizeof(list1[0]); n++) {
        word1 = list1[n];
        for (int m = 0; m < sizeof(list2)/sizeof(list2[0]); m++) {
            word2 = list2[m];
            for (int o = 0; o < sizeof(list3)/sizeof(list3[0]); o++) {
                word3 = list3[o];
                for (int p = 0; p < sizeof(list4)/sizeof(list4[0]); p++) {
                    word4 = list4[p];
                    for (int q = 0; q < sizeof(list5)/sizeof(list5[0]); q++) {
                        word5 = list5[q];
                        string res = word1 + word2 + word3 + word4 + word5;
                        if (compare(res,prize)){ //decode(res) == prize
                            cout<< "Found string " << res << " for seed " << prize << endl;
                            return 0;
                        }
                    }
                }
            }
        }
    }
    cout<< "Seed could not be match with a string"<< endl;
    return 0;
}

如果您尊重 N-API 配置,您的 nodeJS 文件应如下所示:

const addon = require('./build/Release/addon');

//Run some c++ code as an add-on of NodeJS
const runAddon = () => addon.main();
runAddon();

编辑:添加示例 + C++ 代码


推荐阅读