С нами с 17.08.05
Сообщения: 135
Рейтинг: 78
|
Добавлено: 25/11/11 в 20:53 |
всем привет.
очень нуждаюсь в быстром скрипте для рандомного shuffle записей внутри файла. записей более 20лямов.
такие варианты как:
1) cat list| sort -R >list- (под дебиан)
2) cat shuffle.pl
#!/usr/bin/perl -w
srand(time|$$);
@a = <>;
while ( @a ) {
$choice = splice(@a, rand @a, 1);
print $choice;
}
3) cat shuffle2.pl
#!/usr/bin/perl
while (<>) {
$mysort{$_}++;
}
foreach $str (keys %mysort) {
print $str
}
работают плохо и долго.
подскажите хороший скрипт.
|
|
|
|
С нами с 15.04.08
Сообщения: 43
Рейтинг: 33
|
Добавлено: 26/11/11 в 03:32 |
не проще засунуть все записи в базу, сделать нужные индексы и рандомно выбирать из базы ?
|
|
|
|
С нами с 07.10.01
Сообщения: 4835
Рейтинг: 3672
|
Добавлено: 26/11/11 в 11:41 |
А что насчёт php shuffle?
Вот тут есть пример быстрой сортировки. Вкратце - там в массив грузятся не строки целиком, а только позиции начала строк (т.е. числа). Фактически, что-то вроде индексов, для текстового файла. На 500k строк он тестировал, не знаю как насчёт двух лямов будет, но попробовать можно - должно получиться.
Цитата: | If you use the first method, you can load about 50-60k lines for around 25megs of ram, if the lines are about 400-500 characters each. But using the second method (storing line positions), I was able to store 500-550k lines for around 25 megs of ram, which in turn is about 10x more better on ram usage. Alot better! |
|
|
|
|
С нами с 24.10.04
Сообщения: 18881
Рейтинг: 9010
|
Добавлено: 26/11/11 в 11:50 |
на думаю, что рнр будет быстрее...
как вариант попробовать разбить файл на мелкие части, через систему, по 1м строк:
split -l 1000000 /pathtofil/myfile
только не уверен, что будет большой выигрыш по времени
о каком времени и объемах идет речь хорошо бы уточнить
|
|
|
|
С нами с 17.08.05
Сообщения: 135
Рейтинг: 78
|
Добавлено: 26/11/11 в 16:53 |
может пригодиться кому:
cat newlines.pl
#!/usr/bin/perl
use strict;
use warnings;
# Prepare
if(scalar @ARGV < 2) {
print STDERR "Usage: newlines.pl <infile> <outfile>\n";
exit 1;
}
my ($infile, $outfile) = @ARGV;
if(!-e $infile) {
print STDERR "Infile does not exist.\n";
exit 2;
}
if(!open(INFILE, '<', $infile)) {
print STDERR "Unable to open infile.\n";
exit 3;
}
# Load lines
my @lines = ();
my ($n, $f) = (0, 0);
while(<INFILE>) {
push(@lines, $_) and $n++;
}
close(INFILE);
# Shuffle
srand;
while(--$n) {
$f = int(rand($n + 1));
next if $n == $f;
@lines[$n, $f] = @lines[$f, $n];
}
# Output
open(OUTFILE, '>', $outfile);
foreach(@lines) {
print OUTFILE $_;
}
close(OUTFILE);
exit 0;
файл: 600мег, 26лямов строк
время работы скрипта составило полминуты !!!
процесс правда отожрал 2.5гига памяти.
|
|
|
|
С нами с 07.10.01
Сообщения: 4835
Рейтинг: 3672
|
Добавлено: 26/11/11 в 22:36 |
FreeMann писал: | может пригодиться кому... |
Это чтобы сервер класть?
2.5 гига )
|
|
|
|
www.phpdevs.com
С нами с 24.10.02
Сообщения: 16633
Рейтинг: 16105
|
Добавлено: 26/11/11 в 23:26 |
А почему бы не загнать все это в базу и оттуда кроном генерить уже созданные рандомные куски ?
Скажем каждую минуту берем рандомно 10к записей и их используем.
|
|
Пишу на php/mysql/django за вменяемые деньги.
Обращаться в личку.
|
0
|
|
|
С нами с 17.08.05
Сообщения: 135
Рейтинг: 78
|
Добавлено: 27/11/11 в 12:24 |
kodek писал: | Это чтобы сервер класть?
2.5 гига ) |
почему класть
сейчас дедики 16-96гигами оперативки не так и дорого стоят. так что если и отожреться процессом 2.5гига - то даже и заметно не будет.
все советы с базой не подходят, т.к. лист постоянно дополняется и рандомить нужно весь лист целиком, да и как то более громоздно мне кажеться если еще и базу для этого подключать...
спасибо всем.
|
|
|
|