необходимо создать текстовый документ с 1млн строк
запись
от 0000000
до 0999999
все должно быть вперемешку
и чтобы все номера были уникальными
посоветуйте алгоритмы которыми бы вы пользовались.
Время выполнения скрипта играет роль.
Мой вариант:
1) Заолнить mysql 1млн строк по порядку от 0000000 до 0999999
$i=0;
while( $i<1000000 )
{
$chislo = sprintf("%07d", $i); // приводим к виду с нулями 0000001
mysql_query ("INSERT INTO `rand2` ( `num`, `chislo`) VALUES ( '$i', '$chislo' ) ");
$i++;
}
2)формируем массив
$result = mysql_query("SELECT `chislo` FROM `rand3` WHERE `num`>=0 And `num`<1000000 ") or die("Invalid query: " . mysql_error()) ;
while ( $my_arr= mysql_fetch_assoc($result) )
{
$million[]= $my_arr['chislo']; // заполняем массив
}
3) перемешать массив
shuffle($million);
4) Заполнить текстовый файл
$fp = fopen("million_ab.txt", 'a'); // Открываем файл в режиме записи
ftruncate($fp, 0) ; // Очищаем файл если не пустой
foreach( $million AS $key => $ind )
{
$dok= $prefiks.$ind."\r\n";
$test = fwrite($fp, $dok); // построчно заносим данные в файл
}
fclose($fp); // закр. док
Алгоритм занимает 110 секунд на запись данных в БД
еще 20 сек на создание массива
6 на его перемешивание и занесение в документ.
Это хорошо, но хочется лучше.
Есть какие варианты?
Уж больно долго он формирует бд.
Спустя 5 минут, 52 секунды (12.07.2011 - 16:46) Invis1ble написал(а):
Цитата |
Уж больно долго он формирует бд. |
ясен пень, ты ж делаешь лям запросов

в то время, как можно это сделать ~1-10 (зависит от настроек мускула, в частности от лимита на размеры пакетов)
по сути: зачем изврат с БД, почему бы сразу не записать в файл?
Спустя 4 минуты, 36 секунд (12.07.2011 - 16:50) Invis1ble написал(а):
$arr = range(0, 999999);
shuffle($arr);
$fh = fopen($filename, 'w');
foreach ($arr as $v)
fwrite($fh, $v . PHP_EOL);
fclose($fh);
UPDATE. Даже так:
$arr = range(0, 999999);
shuffle($arr);
$arr = array_map(create_function('$v', 'return sprintf("%07d", $v);'), $arr);
file_put_contents($filename, implode(PHP_EOL, $arr));
Спустя 28 минут, 41 секунда (12.07.2011 - 17:19) Invis1ble написал(а):
как вариант, попробовать str_pad() вместо sprintf():
$arr = array_map(create_function('$v', 'return str_pad($v, 7, "0", STR_PAD_LEFT);'), $arr);
Спустя 14 минут, 22 секунды (12.07.2011 - 17:33) kuzroman написал(а):
Да спасибо. Ваш запрос работает 2 секунды, здорово))
Еще и узнал про иной способ занесения инфы в файл.
Еще и узнал про иной способ занесения инфы в файл.
Спустя 33 минуты, 39 секунд (12.07.2011 - 18:07) kuzroman написал(а):
Цитата (Invis1ble @ 12.07.2011 - 14:19) |
как вариант, попробовать str_pad() вместо sprintf():$arr = array_map(create_function('$v', 'return str_pad($v, 7, "0", STR_PAD_LEFT);'), $arr); |
НЕ подскажете почему
str_pad($v, 7, "0", STR_PAD_LEFT); выполняется и при записи 10 млн строк, а
sprintf("%07d", $i); не работает уже на 4млн
пишет
Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 240 bytes) in W:\home\localhost\www\random\random_file_txt_new.php on line 10
Почему файл сформированный с помощью str_pad() занимает меньше памяти?
Ведь строки и там и там одинаковой длинны или символы переноса разные?
Спустя 6 минут, 7 секунд (12.07.2011 - 18:13) Winston написал(а):
Потому, что sprintf очень тяжелая, а str_pad очень шустрая
Чтобы небыло
Чтобы небыло
Цитата (kuzroman @ 12.07.2011 - 18:07) |
Fatal error: Allowed memory size of 1073741824.... |
В начале файла пишем
set_time_limit(0);
ini_set('memory_limit', '32M');
Или ставим столько Мб сколько вам не жалко.
Спустя 2 минуты, 29 секунд (12.07.2011 - 18:15) Invis1ble написал(а):
не уверен, но есть предположение, что это баг функции sprintf(), что-то типа переполнения буффера
можно попробовать использовать не анонимную ф-цию
можно попробовать использовать не анонимную ф-цию
function padding($v)
{
return sprintf("%07d", $v);
}
$arr = array_map('padding', $arr);
_____________
kuzroman@list.ru