как работать с массивом данных?

danneo

Честный
Регистрация
13 Ноя 2007
Сообщения
1.526
Реакции
121
Есть фирмы, например, 1000 штук. У каждой фирмы есть результат опроса в баллах (например, у каждой по 200 штук).
Получается 200 000 записей.
Мне нужно будет с этими результатами проводить вычисления.
Придумал только два способа работы:
1. сформировать многомерный массив
PHP:
arr['id_firm']
  ['0']['res'] = 4.6
  ['1']['res'] = 2.9
  ['2']['res'] = 5.7

arr['id_firm']
  ['0']['res'] = 4.6
  ['1']['res'] = 2.9
  ['2']['res'] = 5.7

Но учитывая, что 200 000 записей, то какой-то весомый массив будет.

2. сформировать файлы po_id_firm.txt для каждой фирмы свой, с названием фирмы (ее id). Далее, при переборе выборки из БД, данные складывать в эти файлы (добавляя в конец файла строку).
Файлов будет много, но зато можно будет потом взять файл и создать из него массив.

Или как еще можно сделать? Проблема в том, что я не разбираются в нагрузке, что будет быстрее, что тормозить.
Вообще, планирую это делать либо на локальном ПК, делая выгрузку с сайта, либо на стороннем сайте (удаленно), чтобы не нагружать сам сайт.
 
Какого рода вычисление будут проводиться?

Почему нельзя это хранить в БД? Которые в общем-то для того и предназначены, чтобы при оптимальной нагрузке делать выборки из массива данных.

Вот кстати синтетический тест для создания массива на 200к элементов и заполнения рендомными значениями похожими на ваши.
PHP:
$arr = range(0, 200000);
array_walk($arr, function (&$val) {
  $val = rand(0, 99) / 10;
});
var_dump(    count($arr)    );


var_dump(    memory_get_peak_usage(true)    );
У меня в пике 18Мб памяти ест, если это допустимо то можно и одним файлом хранить.
 
Если обрабатывать этот массив надо не постоянно и не критично реалтайм обновление аналитики, то 200000 чисел в массиве, то это не большие данные, чтобы их в одном массиве хранить. Хотя всё зависит ещё от того как вы это всё будете обрабатывать.

Вот просто тест на сложение всех элементов:

PHP:
<?php

$arr = array();
$mtime = explode(" ",microtime());
$tStart = $mtime[1] + $mtime[0];

echo "Старт = " . memory_get_usage()/1000000 . "Мб. <br>";

for ($i=0;$i<=1000;$i++) {
    $arr[$i] = array();
    for ($j=0;$j<=200;$j++) {
        $arr[$i][$j] = rand(0,10);
    }
}

echo "Сформировали массив = " . memory_get_usage()/1000000 . "Мб. <br>";

$sum = 0;
foreach ($arr as $firm) {
    foreach ($firm as $value) {
        $sum = $sum + $value;
    }
}

echo "После обработки массива = " . memory_get_usage()/1000000 . "Мб. <br>";

for ($i=0;$i<=100;$i++) {
    unset($arr[$i]);
}

echo "После удаления первых 100 элементов = " . memory_get_usage()/1000000 . "Мб. <br>";

echo "Пиковое значение = " . memory_get_peak_usage()/1000000 . "Мб. <br>";

$mtime = explode(" ",microtime());
$mtime = $mtime[1] + $mtime[0];
$totaltime = ($mtime - $tStart);

echo "Затрачено времени = " . $totaltime . " c. <br>";


На выходе:
Старт = 0.141888Мб.
Сформировали массив = 17.411664Мб.
После обработки массива = 17.411856Мб.
После удаления первых 100 элементов = 15.669768Мб.
Пиковое значение = 17.42508Мб.
Затрачено времени = 1.2103190422058 c.
 
Вот просто тест на сложение всех элементов
...
Затрачено времени = 1.2103190422058 c.

Несколько замечаний, которые помогут вам писать более быстрый код:
В php есть нативная Для просмотра ссылки Войди или Зарегистрируйся которая будет работать быстрее прохода массива через цикл.
Над microtime не надо делать explode, лучше сразу получить в нужном формате microtime(TRUE)
Очень много времени тратится на создание и заполнение массива рендомными данными выполнять замеры по времени лучше после создания, поскольку у ТС эта операция будет отсутсвовать.
 
Несколько замечаний, которые помогут вам писать более быстрый код:
В php есть нативная Для просмотра ссылки Войди или Зарегистрируйся которая будет работать быстрее прохода массива через цикл.
Над microtime не надо делать explode, лучше сразу получить в нужном формате microtime(TRUE)
Очень много времени тратится на создание и заполнение массива рендомными данными выполнять замеры по времени лучше после создания, поскольку у ТС эта операция будет отсутсвовать.

спасибо, конечно. за кодревью :) смешно
Тут не было задачи написать быстрый код и написать его быстро, а наоборот как-то сымитировать перебор массива и вычисления, понятно. что тут имитация ни о чём, но всё же.
 
Какого рода вычисление будут проводиться?

Почему нельзя это хранить в БД? Которые в общем-то для того и предназначены, чтобы при оптимальной нагрузке делать выборки из массива данных.
С каждым результатом опроса будут проводиться различные статистические вычисления. Например, в зависимости от даты опроса, определить устаревание значимости, сумму таких опросов и сумму всех результатов по одной фирме. Потом сумму по всем фирмам всех результатов и всех баллов с учетом устаревания, среднее арифметическое и т.п.
И все эти данные в БД хранить не вижу смысла. Завтра они уже устареют и нужно пересчитывать. Но вот результат всех вычислений нужно будет уже сохранить в БД.

В общем, сначала нужно сформировать массив по каждой фирме. Далее будет вычисляться параметр и добавляться как элемент еще один массива в соответствующему результату. Т.е. у каждого результата голосования будет несколько элементов, например, балл, среднее арифм, сумму всех баллов, сумму кол-ва опросов и т.д.
['0']['res'] = 4.6
['0']['summ'] = 4.6
['0']['arifm'] = 4.6
где 0 - результат опроса, а далее различные вычисления.
Таким образом, массив получится в раз 5 больше, чем я указал :)

Поэтому, я так думаю, что процесс будет выглядеть примерно следующим. Сформировать массив всех фирм, проходя по каждому элементу, будет считаться значения. Перебор массива будет примерно раза 3, наверно.

Надеюсь, что описал, чего хочу :)

Ладно, убедили :). попробую сделать в массиве. Спасибо.

Еще, как вариант, если будет большая нагрузка, можно сделать запуск скрипта через крон. Выбирать по одной фирме и все ее результаты, и обрабатывать. Затем другую. Потом общие данные по всем фирмам останутся.


А все же, Latteo, а что в БД сохранять в таком случае?
 
Последнее редактирование:
Подумалось мне, глядя на это
PHP:
  ['0']['res'] = 4.6
  ['1']['res'] = 2.9
  ['2']['res'] = 5.7
что это некие оценки, каждый день они прибавляются и их все надо хранить, при добавлении оценки пересчитывать некую статистику - в таком случае было бы лучше использовать БД
Подсчитать при таком раскладе SQL запросом сумму или среднее будет гораздо быстрее чем каждый раз перечитывать файл и высчитывать это на php

Если ты в течении дня заполняешь некую статистику, а потом один раз по крону делаешь вычисления и удаляешь данные, то вполне возможно, что база окажется медленнее...
Но при работе с файлами не забудь блокировать файл и продумать логику, чтобы не вышло приколов, когда один скрипт из файла удалит всё, а другой восстановит.
 
Назад
Сверху