Ускорение разбиения текста c++

323
30 января 2017, 18:10

Требуется разбить большой файл (1 600 000 строк) на строки и сохранить в коллекцию с уникальными значениями. Подгрузка файла происходит на javascript, полученный из файла текст отправляется в модуль на c++, где происходит разбивка файла по строкам. Созданная коллекция возвращается обратно в js. Код который мне удалось написать:

C++:

#include <node.h>
#include <v8.h>
#include <string>
#include <sstream>
#include <iterator>
using namespace v8;
// Split function --------------------------------------------------------------
template<typename Out>
void split(const std::string &s, char delim, Out result) {
    std::stringstream ss;
    ss.str(s);
    std::string item;
    while (std::getline(ss, item, delim)) {
        *(result++) = item;
    }
}
std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, std::back_inserter(elems));
    return elems;
}
// Dictionary parse ------------------------------------------------------------
void Parse(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    Local<Context> context = isolate->GetCurrentContext();
    // Set для записи слов
    Local<Set> Words = Set::New(isolate);
    // Проверка аргумента на тип
    if (!args[0]->IsString()) {
        isolate->ThrowException(
            Exception::TypeError(
                String::NewFromUtf8(isolate, "Wrong type of first argument")
            )
        );
        return;
    }
    // Конвертим аргумент в строку
    String::Utf8Value arg(args[0]->ToString());
    std::string dictInput = std::string(*arg);
    // Разбиение строки в вектор
    std::vector<std::string> v = split(dictInput, '\n');
    // Перебор вектора
    std::vector<std::string>::iterator it = v.begin();
    for (it; it != v.end(); ++it) {
        // Сохраняем слово в коллекцию
        Words->Add(context, String::NewFromUtf8(isolate, (*it).c_str()));
    }
    // Возвращаем получившийся Set
    args.GetReturnValue().Set(Words);
}
// Module exports --------------------------------------------------------------
void Init(Local<Object> exports, Local<Object> module) {
    NODE_SET_METHOD(module, "exports", Parse);
}
NODE_MODULE(addon, Init)

Javascript:

const fs = require('fs');
const readDict = require('./build/Release/read-dictionary')
let text = fs.readFileSync('./dictionary.txt', 'utf8')
let WORDS = readDict(text);

Проблема состоит в том, что код на C++ работает дольше 2200 мс, в то время как аналогичный код на js работает около 1550 мс, что тоже очень долго (и занимает всего десять строк, да):

const fs = require('fs');
let WORDS = new Set()
let file = fs.readFileSync('file.txt')
let list = text.split('\n')
for (let i = 0; i < list.length; i++) {
    // Быстрее, чем "WORDS = new Set(list)"
    WORDS.add(list[i++])
}

С целью ускорить обработку и была предпринята попытка написания на C++, но пока не очень удачная. ++ я не знаю совсем, сегодня первый день как пишу на нём. Есть какие-то способы ускорить всё это?

Спасибо

READ ALSO
Как создать оператор += для Point c++ [требует правки]

Как создать оператор += для Point c++ [требует правки]

Нужно создать такой оператор Point& operator+=(Point &, const Point&)

353
Как создать getter для класса Pont c++ [требует правки]

Как создать getter для класса Pont c++ [требует правки]

Помогите создать getter для класса Point double& x();

330
Программное создание VPN подключения на Windows

Программное создание VPN подключения на Windows

Есть VPN сервер и я к нему подключаюсь по протоколу PPTP или L2TP с помощью стандартных средств виндовс, аля http://skynetcom

322
Перегрузка оператора сложения

Перегрузка оператора сложения

Казалось бы все пишу правильно, сложение двух котов даст нового кота, у которого value будет суммой их value'овНо получаю две ошибки

643