У меня есть числовой двумерный массив (массив массивов или матрица), и мне нужно выполнять простые матричные операции, такие как добавление значения к каждой строке или умножение каждого значения на одно число. У меня мало опыта с математическими операциями в JavaScript, так что это может быть фрагмент кода с костяком. Это также очень медленно, и мне нужно использовать его, когда количество столбцов составляет 10 000–30 000. Под очень медленным я подразумеваю примерно 500 мс для обработки строки из 2000 значений. облом.

var ran2Darray = function(row, col){
    var res = [];
    for (var i = 0 ; i < row; i++) {
        res[i] = [];
        for (var j = 0; j < col; j++) {
            res[i][j] = Math.random();
        }
    }
    return res;
}

var myArray = ran2Darray(5, 100);
var offset = 2;

for (i = 0; i < myArray.length; i++) {
    aRow = myArray[i];
    st = Date.now();
    aRow.map(function addNumber(offset) {myArray[i] + offset*i; })
    end = Date.now();
    document.write(end - st);
    document.write("</br>");
    myArray[i] = aRow;
}

Я хочу избежать каких-либо добавленных библиотек или фреймворков, если, конечно, это не единственный вариант. Можно ли сделать этот код быстрее или есть другое направление, в котором я могу пойти, например, передать вычисление другому языку? Я просто не знаю, как люди решают подобные проблемы. Кстати, forEach работает примерно так же.

0
Bryan Hanson 3 Мар 2015 в 01:28
1
Array.map, а также forEach вызывают функцию для каждого элемента. Попробуйте заменить это циклом for.
 – 
levi
3 Мар 2015 в 01:32
Вы правы! Спасибо, это то, что я еще не очень ценю в JavaScript. На моем обычном языке, R, такие вещи очень оптимизированы, и версия с отображением обычно быстрее. Я переписал его, чтобы использовать 2 индекса, и для матрицы 5 x 50000 это заняло 7 мс. Ответ от @Artyom занял 47 мс (но я узнал несколько вещей из этого ответа).
 – 
Bryan Hanson
3 Мар 2015 в 02:03

2 ответа

Хорошо, просто небольшая модификация и исправление ошибки в том, что вы здесь представили.

function addNumber(offset) {myArray[i] + offset*i; }) is not good.

MyArray[i] - это первое измерение двумерного массива, зачем к нему что-то добавлять?

function ran2Darray (row, col) {

    var res = [];

    for (var i = 0 ; i < row; i++) {

        res[i] = [];

        for (var j = 0; j < col; j++) {
            res[i][j] = Math.random();
        }
    }
    return res;
}

var oneMillion = 1000000;
var myArray = ran2Darray(10, oneMillion);
var offset = 2;
var startTime, endTime;

for (i = 0; i < myArray.length; i++) {

    startTime = Date.now();
    myArray[i] = myArray[i].map(function (offset) {

        return (offset + i) * offset;
    });
    endTime = Date.now();

    document.write(endTime - startTime);
    document.write("</br>");
}

Попытайся. Это очень быстро https://jsfiddle.net/itaymer/8ttvzyx7/

1
Itay Merchav 3 Мар 2015 в 02:45
Спасибо, побольше хороших вещей для изучения. Выглядит немного медленнее, чем ответ @Artyom. Очень признателен, я знал, что делаю это не совсем правильно.
 – 
Bryan Hanson
3 Мар 2015 в 02:30

Вам не нужно переписывать элементы массива несколько раз. .map() возвращает новый массив, поэтому просто присвойте его текущему индексу:

var myArray = ran2Darray(5, 100000);
var offset = 2;

var performOperation = function(value, idx) {
    return value += offset * idx;
}

for (i = 0; i < myArray.length; i++) {
    console.time(i);
    myArray[i] = myArray[i].map(performOperation)
    console.timeEnd(i);
}

Обработка занимает около 20 мс.

Демонстрация Fiddle (открытая консоль)

1
Artyom Neustroev 3 Мар 2015 в 01:44
Спасибо, это было очень полезно и быстро, хотя и немного медленнее, чем просто использование двух циклов (см. комментарий к исходному вопросу). Я узнал пару полезных вещей из вашего примера.
 – 
Bryan Hanson
3 Мар 2015 в 02:05