Master-X
Регистрация
|
Вход
Форум
|
Новости
|
Статьи
Главная
»
Форум
»
Программинг, Скрипты, Софт, Сервисы
»
Тема:
Быстрый shuffle скрипт
Новая тема
Ответить
цитата
25/11/11 в 20:53
FreeMann
всем привет.
очень нуждаюсь в быстром скрипте для рандомного 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
}
работают плохо и долго.
подскажите хороший скрипт.
цитата
26/11/11 в 03:32
msth
не проще засунуть все записи в базу, сделать нужные индексы и рандомно выбирать из базы ?
цитата
26/11/11 в 11:41
kodek
А что насчёт 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!
цитата
26/11/11 в 11:50
ibiz
на думаю, что рнр будет быстрее...
как вариант попробовать разбить файл на мелкие части, через систему, по 1м строк:
split -l 1000000 /pathtofil/myfile
только не уверен, что будет большой выигрыш по времени
о каком времени и объемах идет речь хорошо бы уточнить
цитата
26/11/11 в 16:53
FreeMann
может пригодиться кому:
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гига памяти.
цитата
26/11/11 в 22:36
kodek
FreeMann писал:
может пригодиться кому...
Это чтобы сервер класть?
2.5 гига )
цитата
26/11/11 в 23:26
Stek
А почему бы не загнать все это в базу и оттуда кроном генерить уже созданные рандомные куски ?
Скажем каждую минуту берем рандомно 10к записей и их используем.
цитата
27/11/11 в 12:24
FreeMann
kodek писал:
Это чтобы сервер класть?
2.5 гига )
почему класть
сейчас дедики 16-96гигами оперативки не так и дорого стоят. так что если и отожреться процессом 2.5гига - то даже и заметно не будет.
все советы с базой не подходят, т.к. лист постоянно дополняется и рандомить нужно весь лист целиком, да и как то более громоздно мне кажеться если еще и базу для этого подключать...
спасибо всем.
Новая тема
Ответить
Эта страница в полной версии