perlunity.de - PERL | JAVASCRIPT | PHP | MySQL | APACHE



#!/COMMUNITY

Members: 5374
davon online: 1
weitere User: 24
Click for quality!




11.02.2012 / 23:34

Community-Member werden   |   Paßwort vergessen   |   OnlineMonitor (1) Wer ist online ... OnlineMonitor starten !
     

 

Home


PERLscripts


PHPscripts


JAVAscripts


Hilfreiches


Links2www


Newscenter


Community


Interna




Community  »  Suchanfragen für Scripts/Programmierung zur Themenübersicht Themensuche Themenansicht in Thread-Modus


BeitragSuche ist zu langsam
Seitenanfang
Hallo Profis,

ich habe folgendes Problem mit dieser suchroutine. Ich habe eine ca. 13MB große textdatei und will die durchsuchen, aber irgendwie ist mir das zu langsam. dauert fast 10 sekunden. Kann man am Code was ändern, damit das ganze mindestens 50% oder schneller wird? Danke und Gruss Orta

sub suchen {
my (%ausgabe, %ausgaben) = ();
my $suchworte = shift;
my $suchalles = shift || '0';
$suchalles = '1' if ($suchabgleich);
my @fields = @suchFelder;
return undef if (!$suchworte);
my $datenbankColZaehler = $#datenbankC+1;
my %werteSuche = (
'keywordEnthaltenInSuchworte' => '1',
);
($suchworte) and (my @rawQWords = split(/\s/, $suchworte));
my @qWords = ();
foreach (@rawQWords) {
push(@qWords, $_) if ($_ !~ /^\s*$/);
}
my $cqw = $#qWords;
open (DB, "<eintraege.txt") or die print "Problem beim öffnen der Datenbank: eintraege.txt. Reason: $!\n";
flock(DB,2);
while (<DB>) {
/^#/ and next;
/^\s*$/ and next;
chomp($_);
my $line = $_;
my @values = &split_decode($line);
my $id = $values[$konfiguration{'datenbankSID'}];
if ($cqw >= '0') {
my %t_it = ();
my $i = '0';
foreach my $suchworte (@qWords) {
$t_it{$id}[$i] = '0';
foreach my $col (@fields) {
my $value = $values[$col];
next if (!$value);
$value =~ tr/A-Z/a-z/;
$value =~ s/['.,?!]/ /g;
$value =~ s/\s+/ /g;
($value) and (my @keyWords = split(/\s/, $value));
foreach my $dataWord (@keyWords) {
($dataWord) or next;
if ($suchalles) {
if ($dataWord =~ /$suchworte/) {
$t_it{$id}[$i] = $t_it{$id}[$i] + $werteSuche{'keywordEnthaltenInSuchworte'};
}
}
}
}
$i++
}
my %t_to = ();
my %t_me = ();
foreach (keys %t_it) {
for (my $i = 0; $i <= $cqw; $i++) {
if (@{$t_it{$_}}[$i]) {
$t_to{$_}++;
(!exists $t_me{$id}) and ($t_me{$id} = '0');
$t_me{$id} = $t_me{$id} + @{$t_it{$_}}[$i];
}
}
(!exists $t_to{$id}) and ($t_to{$id} = '0');
($t_to{$id} == ($cqw + 1)) and ($ausgabe{$id} = $t_me{$id});
}
}
if (exists $ausgabe{$id}) {
@{$ausgaben{$id}} = @values;
@{$ausgaben{$id}}[$datenbankColZaehler] = $ausgabe{$id};
}
}
close DB;
return %ausgaben;
}

Datum: 11.11.2005-04:58

Beitragre: Suche ist zu langsam
Seitenanfang
Hallo,

ich hab mir Dein Programm nicht ganz reingezogen, aber probier mal eine ganz andere Vorgehensweise:

1. Alle Suchbegriffe zu einem RegEx mit '|' zusammanbauen
2. Datei zeilenweise einlesen
2.1 Jede Zeile gegen RegEx checken
2.2 Spalten nur aufsplitten und auswerten, wenn Treffer

z.B.


my $szSuchRegex = join ( '|', @aSuchworte );

while ( my $szZeile = <DB> ) {

if ( $szZeile =~ /($szSuchReg)/ ) {

# $1= gefundener Suchbegriff
# Zeile zerlegen, Ausgabe aufbereiten

} # end if Treffer

} # end while alle Zeilen

close ( DB );

...Das sollte schnell sein...

Gruß Ralf

Datum: 11.11.2005-09:37

Beitragre: Suche ist zu langsam
Seitenanfang
Hallo Ralf,

vielen Dank für den TIP, aber ich kann damit nichst anfangen. Ich muss unbedingt den Code modifizieren, den ich oben angegeben habe. Ist mir ganz wichtig, da ich da auch eine bestimmte Datenstruktur in einer text-Datei habe, wie z.B so:

1}Thema 1}http://www.thema1.de}Beschreibung1}}}}}}}}}}}}
2}Thema 2}http://www.thema2.de}Beschreibung2}}}}}}}}}}}}}

usw.

Ich habe daher nur diesen Codeschnippsel und wollte da sunbedingt damit lösen. Ich würde mich riesig freuen, wenn man den Codeschnippsel so modifiziert, das man da unbrauchbares rasuschneidet. Mir scheint der Code auch etwas zuviel für eine Suchabfrage. Ich würde mich auch über Tipps freuen, was ich an dem Code ändern bzw. löschen könnte oder versuchen könnte zu löschen. ich selbst habe schon viel asuprobiert, aber es läuft dann nix mehr.

Oben am Anfang des Code wird eine Routine aufgrufen:

my @values = &split_decode($line);

sub split_decode {
my ($input) = shift;
my (@array) = split(/\Q$datentrenner\E/o, $input);
foreach (@array) {
s/~~/$datentrenner/g;
s/``/\n/g;
s/([\xC0-\xDF])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;
}
return @array;
}

Brauch ich das oder kann man das irgenwie kürzen? Kann es daran liegen, das die Suche zu lange dauert? Die Variable $datentrenner ist mit die geschweifte Klammer gemeint, also }-Zeichen. Damit trenne ich die daten in der datenbank.

Gruss
orta

Datum: 11.11.2005-23:39

Beitragre: Suche ist zu langsam
Seitenanfang
Hallo,

ok, dann mach folgendes:

setze trotzdem erstmal einen Regex aus deinen Suchbegriffen zusammen.

Dann häng' als erste Pruefung den Check rein, ob eines der Suchworte ueberhaupt in der Zeile vorkommt..., du verlierst sonst sehr viel Zeit mit dem ganzen aufbröseln der Zeilen, obwohl Du die ja nicht alle brauchst...

while ( <DB> ) {

next unless ( /$szRegEx/ );
...jetzt weiter mit dem Rest

Gruß RAlf

Datum: 13.11.2005-11:25

Beitragre: Suche ist zu langsam
Seitenanfang
Hallo Ralf,

DANKE!!!!!!!!
Ist jetzt schon wesentlich schneller geworden.

Ich habe jetzt nur noch 2 Probleme:
Wenn ich ein nach einem Suchwort suche, ist es schön schnell. Wenn ich 2 Suchworte aber eingebe, ist es etwas langsam.
UND wichtig: Die Suche ist zwar nun schnell, aber wenn ich z.B in der Datenbank irgenwdo stehen haben Berlin, dann findet der das nicht, wenn ich nach "berlin" suche. Das heist, die Groß-und Kleinschreibung stört jetzt. Ich will natürlich das man auch Berlin findet, wenn ich nach berlin suche. Kannst Du mir da nochmal einen Zabertrick sagen, was ich vieleicht an der while-schleife dazufügen muss?
habe es damit mal versucht, aber ging nicht:

next unless ( /$szRegEx/gim );

Also nach dem RegEx nochmal gim eingefügt. Oder muss das gim oder gis oder gism irgendwo anders einprogrammieren?

Gruss
Orta

Datum: 19.11.2005-00:49

Beitragre: Suche ist zu langsam
Seitenanfang

Habe jetzt nochmal die Suche geteste und gemerkt, das der Suchworte die großgeschrieben sind nicht sucht, sondern nur nach Suchworten die kleingeschrieben sind. Das nochmal kurz als Hinweis. Muss ich vieleicht am Regex was ändern? Und ich habe in der Datenbank einige Einträge auch doppelt und wenn ich nach berlin suche bekomme, sehe ich alles doppelten einträge. Kann man da vieleicht einen Duplettenfilter nach dem regex oder vor dem regex schalten?

Gruss und Danke!
Orta

Datum: 19.11.2005-01:02

Beitragre: Suche ist zu langsam
Seitenanfang
Hallo,

das mit Gross/Klein sollte mit:

next unless ( /$szRegEx/i )

erledigt sein.

Für die Doppelten auszublenden wuerde ich so vorgehen:

- Speichere den Suchbegriff (nur kleingeschrieben) eines Treffers im Key eines hashes, und mache next, wenn der bereits vorhanden ist, damit bekommst Du nur den jeweils ersten DB-Eintrag:

----------------------------
( ersetzt next unless ... )

my %hSuchTreffer;

unless ( /$szRegEx/i ) {
next;
} # end unless
else {
next if ( $hSuchTreffer{"\l$1"}++ );
} # end else

Gruß Ralf

Datum: 21.11.2005-09:45

Beitragre: Suche ist zu langsam
Seitenanfang
Hallo Ralf,
Danke, das mit der Klein/Groß-Worten funktioniert nun wunderbar, aber das mit den Dubletten geht irgendwie nicht. Also keine Änderung. Dubletten werden immer noch angezeigt.
Hab so den Code gebaut:

my $szRegEx = join ('|', @rawQWords);
while ( <DB> ) {

my %hSuchTreffer;
unless (/($szRegEx)/i){
next;
} # end unless
else {
next if ($hSuchTreffer{"\l$1"}++);
} # end else

.....

Datum: 22.11.2005-01:11

Beitragre: Suche ist zu langsam
Seitenanfang
hallo Orta,

Du darfst die Definition my %hSuchTreffer nicht in die Schleife reinnehmen, dann initialisiert sich der hash ja mit jedem Durchlauf immer neu...

Gruß Ralf

Datum: 22.11.2005-05:41

Beitragre: Suche ist zu langsam
Seitenanfang

Hallo Ralf,

das mit dem my %hSuchTreffer habe natürlich auch gestern rausgemacht aus der Schleife und ich hatte dann folgendes problem:

Das mit den Dubletten hat dann eigentlich wie ich wollte wunderbar geklappt, ABER, dann hat der alles andere nicht mehr gefunden. Wenn ich nach einen Wort gesucht habe, was nur einmal in der Datenbank war und ich, dann kamen immer NULL treffer. Egal was ich eingebe, immer NULL treffer. Nur bei den Dubletten gehts. Ist merkwürdig. Also die normale suche geht jetzt nicht. Wenn ich die ganzen Schleifen rausnehmen mit dem Dublettenfilter dann geht die Suche auch, aber dann habe ich wieder diese Dubletten. Kannst Du da nochmal was zaubern???

Danke und Gruss Orta

Datum: 22.11.2005-12:57

Beitragre: Suche ist zu langsam
Seitenanfang
Hallo Orta,

das verstehe ich nicht ???
kann fast gar nicht sein !

Schreib mal wieder das Codestück hierher, ggf. kann ein anderer mal drüber schauen...

man sieht ja oft seine eigenen Denkfehler nicht...

Gruß Ralf

Datum: 23.11.2005-09:19

Beitragre: Suche ist zu langsam
Seitenanfang
Hallo Ralf,

sorry das ich etwas spät mich wieder melde. War ein paar Tage unterwegs.
Habe mir jetzt nochmal die ganzen Codes angesehen und es funktioiert nicht 100%. Das heisst, wenn ich diesen Dublettenfilter da einbaue, dann sucht der praktisch nur nach Ergbnissen, die doppelt in der Datenbank vorkommen und alles andere missachtet er. Sprich wenn ich nach Auto suche und das Wort Auto kommt mehr als einmal in der Datenbank vor, dann findet er es auch. Aber wenn cih z.B in der Datenbank nur einmal irgendwo das Wort PKW stehen haben und suche nach PKW, dann findet er es nciht, weil es wohl nur einmal in der Datenbank vorkommt. Ich denke, das in dem Code was geändert werden muss, das er nicht nur nach Dubletten suchen soll, sondern auch das Wort PKW finden soll und nciht ausgrenzen soll, wenn ich danach suche.

Hier nochmal der Code:
...................
open (DB, "<$konfiguration{'datenbankFile'}") or die print "Problem beim öffnen der Datenbank: $konfiguration{'datenbankFile'}. Reason: $!\n";
flock(DB,2);
my %hSuchTreffer;
my $szRegEx = join ('|', @rawQWords);
while ( <DB> ) {
unless (/($szRegEx)/i){
next;
} # end unless
else {
next if ($hSuchTreffer{"\l$1"}++);
} # end else

/^#/ and next;
/^\s*$/ and next;
chomp($_);
..........................

Datum: 28.11.2005-21:01

Beitragre: Suche ist zu langsam
Seitenanfang
Hallo,

ich hab noch was wichtiges vergessen:

um den Treffer auch in $1 zu speichern muß er natürlich erst mal geklammter werden:

unless ( /($szRegEx)/i ) ....

Gruß Ralf

Datum: 21.11.2005-09:51

-






-
-