[PHP] tellen van woordjes

Pagina: 1
Acties:

  • saryon2413
  • Registratie: December 2001
  • Laatst online: 09-12-2021
Hoi,

ik heb een klein scriptje dat woordjes telt in een pagina.
hoe kan ik een snellere versie maken?

huidige versie is:
$aantalwoorden = count(split("[^A-Za-z0-9]+", $text));
//dus: gebruik text, en split op alle niet-alphabet/numerieke
//dingen.
is er iets snellers? ik had eerst met een
replace/split/count, maar dat duurde ongeveer 2 keer zo
lang. *D
maar, deze ene regel duurt bij een redelijk grote text-string
al gauw iets van 10 secondes op een p3-866 !!!!!
(onaanvaardbaar lang :( ) (ik heb het dat over een string
van plm. 250k, komt uit txtfiletje, dus...)

Verwijderd

is explode() niet sneller? dus:

$woorden = count(explode(" ",$string));

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 11:21

Janoz

Moderator Devschuur®

!litemod

Op dinsdag 15 januari 2002 13:09 schreef Freez0r het volgende:
is explode() niet sneller? dus:

$woorden = count(explode(" ",$string));
Nadeel daarvan is dat ie alleen explode op " ", en niet op allemaal andere tekens (Jantje zegt:"hoi.". Dat zijn toch echt 3 woorden en geen 2 :))

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • TheDane
  • Registratie: Oktober 2000
  • Laatst online: 12:34

TheDane

1.618

file inlezen, en dan door tekst scrollen en iedere keer als je zo'n speciaal karakter tegenkomt tellertje ophogen totdat je bij 't eind van de file bent ...

is denk ik wat sneller dan eerst een heel array bouwen met alle woorden erin ...

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 11:21

Janoz

Moderator Devschuur®

!litemod

Op dinsdag 15 januari 2002 13:11 schreef TheDane het volgende:
file inlezen, en dan door tekst scrollen en iedere keer als je zo'n speciaal karakter tegenkomt tellertje ophogen totdat je bij 't eind van de file bent ...

is denk ik wat sneller dan eerst een heel array bouwen met alle woorden erin ...
Euhm... tellertje ophogen waneer je na het inlezen van een normaal karakter een speciaal karakter tegenkomt, anders telt hij dubbel bij ". " en ", " enz.. Dit is trouwens wel de betere manier voor dit probleem :)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

TheDane:
file inlezen, en dan door tekst scrollen en iedere keer als je zo'n speciaal karakter tegenkomt tellertje ophogen totdat je bij 't eind van de file bent ...

is denk ik wat sneller dan eerst een heel array bouwen met alle woorden erin ...
ik denk niet dat daar de bottleneck zit. Als dat wel zo zou zijn zou het uberhaupt niet handig zijn dat die functies bestaan ;)

probeer deze eens:
code:
1
$words = preg_split ( "/\W/", $string );

edit
_________________________________________________
Als je die + uit je splitstring weghaalt zal het ook een stuk sneller gaan. Die heeft nl. helemaal geen zin

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Op dinsdag 15 januari 2002 13:11 schreef Janoz het volgende:

[..]

Nadeel daarvan is dat ie alleen explode op " ", en niet op allemaal andere tekens (Jantje zegt:"hoi.". Dat zijn toch echt 3 woorden en geen 2 :))
'Jantje zegt:"hoi.".' klopt ook niet.

Maar ik denk eerder dat de vraag is hoe je woorden gaat tellen.

Hoeveel woorden zijn dit?

"Jantje is 8 jaar.Morgen wordt ie 9."

8, 7 of 6?

explode zal hem opsplitsen in 7 en dat klopt volgens mij ook. Een punt mag je niet als seperator gebruiken anders zit je met afkortingen te klooien (b.v., n.a.v. etc.).

Als je in MS Word een wordcount doet komt ie ook netjes op 7.

En met 'Jantje zegt:"hoi." komt ie netjes op 2.

<edit: lezen is een vak>

  • saryon2413
  • Registratie: December 2001
  • Laatst online: 09-12-2021
Op dinsdag 15 januari 2002 13:14 schreef drm het volgende:

[..]
probeer deze eens:
code:
1
$words = preg_split ( "/\W/", $string );

Als je die + uit je splitstring weghaalt zal het ook een stuk sneller gaan. Die heeft nl. helemaal geen zin
ok, +'je verwijderd...leuke verbetering van tot 6keer sneller :) (gem: 2keer)
probeer nu die preg_split, eens kijken of dat verschil maakt of niet.
over het algemeen is het een tikkie sneller, soms trager.
varieert van 5 * trager tot 100* sneller ( :? )

nu nog ff kijken of de text die ik ingevoerd heb ook goed er
uit komt ;)
hmmm....afgezien van de ----'tjes en zo, goede resultaten.

crea trouwens....als er geen empty values teruggegeven mogen
worden, wordt er slechts 1 veld teruggegeven, maar dan
wel een die NIET gesliptst is, en de complete text heeft. :?

bedankt :)
scheelt weer een hoop tijd en zo :)

nu nog al die lege veldjes eruit zien te zetten....

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

MarcoTC:
(...)
En met 'Jantje zegt:"hoi." komt ie netjes op 2.
Je zou dan kunnen overwegen om niet-nette strings om te zetten in wel-nette strings (is dat nederlands :?)

iets van:
code:
1
2
3
4
5
6
$leestekens = array (
   ":", ".", ",", ";", "\"", "'", ...etc...
);

foreach ( $leestekens as $t )
   $str = preg_replace ( "/$t(\S)/", "$t \\1" );

maar ja, dat kost natuurlijk nog weer extra tijd.
saryon2413:
crea trouwens....als er geen empty values teruggegeven mogen
worden, wordt er slechts 1 veld teruggegeven, maar dan
wel een die NIET gesliptst is, en de complete text heeft. :?
staat wel e.e.a. over in de manual als het goed is.
bedankt :)
scheelt weer een hoop tijd en zo :)
np :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • saryon2413
  • Registratie: December 2001
  • Laatst online: 09-12-2021
Hoeveel woorden zijn dit?

"Jantje is 8 jaar.Morgen wordt ie 9."

8, 7 of 6?
"Jantje is 8 jaar.Morgen wordt ie 9."
1 2 3 4 5 6 7 8

ik kom op 8.

De getallen moeten (volgens de rekening) ook meegeteld
worden, en alle niet-alphanumerieke tekens (zie regexp)
worden eruitgefiltert en op gesplitst.

trouwens.....wat word doet kan me eigenlijk niet echt
veel schelen, want die kan niet eens correct nederlands,
zelfs niet met correcte woordenboek (ps: ik ook niet, maar
dat is iets anders ;))

  • saryon2413
  • Registratie: December 2001
  • Laatst online: 09-12-2021
Op dinsdag 15 januari 2002 14:23 schreef drm het volgende:

[..]

Je zou dan kunnen overwegen om niet-nette strings om te zetten in wel-nette strings (is dat nederlands :?)
vast wel.
iets van:
code:
1
2
3
4
5
6
$leestekens = array (
   ":", ".", ",", ";", "\"", "'", ...etc...
);

foreach ( $leestekens as $t )
   $str = preg_replace ( "/$t(\S)/", "$t \\1" );

maar ja, dat kost natuurlijk nog weer extra tijd.
[..]
ja....dat dus liever niet. scriptje mag niet al te lang
duren, want er zitten nog andere dingen bij, die ik
ook nog moet optimaliseren, en het duurt nog steeds een
kleine 3 minuten om het af te maken (ivh de 5 die het was)
(als ik tenminste een kleine 2.5 meg aan text heb dus, he;))

  • TheDane
  • Registratie: Oktober 2000
  • Laatst online: 12:34

TheDane

1.618

Op dinsdag 15 januari 2002 13:14 schreef drm het volgende:

[..]

ik denk niet dat daar de bottleneck zit. Als dat wel zo zou zijn zou het uberhaupt niet handig zijn dat die functies bestaan ;)
nou, dat weet ik nog zo net niet ...
split() / explode() doen in feite niks anders dan checken of ze een bepaald karakter tegenkomen (en regex is over 't algemeen nog trager omdat ie ook nog eens de expressie moet evalueren)

en da's dus 'tzelfde als wat ik doe, alleen split / explode zet 't OOK nog eens in een (overbodig) array .. dus daar verlies je zowiezo al tijd & geheugen op ...

  • saryon2413
  • Registratie: December 2001
  • Laatst online: 09-12-2021
Op dinsdag 15 januari 2002 14:30 schreef TheDane het volgende:

[..]

nou, dat weet ik nog zo net niet ...
split() / explode() doen in feite niks anders dan checken of ze een bepaald karakter tegenkomen (en regex is over 't algemeen nog trager omdat ie ook nog eens de expressie moet evalueren)

en da's dus 'tzelfde als wat ik doe, alleen split / explode zet 't OOK nog eens in een (overbodig) array .. dus daar verlies je zowiezo al tijd & geheugen op ...
geheugen boeit niet echt veel, ik heb 10 meg te gebruiken,
en heb nog genoeg vrij, en ik krijg meer geheugen vrij
en ik stop de array die ik terug krijg niet in een array,
en heb dus bijna meteen dat geheugen dat wordt gebruikt
door de array bijna meteen weer terug (even niet voor
de duur van de count()).
bij iedere ronde die doorlopen wordt (leve unset())
En als ik nog te weinig geheugen heb, kan ik de sysbeheerder
ff vragen of ie nog ff 5 meg reserveert voor me, hoewel ik
natuurlijk wel het zooitje een beetje binnen de perken
probeer te houden

om een lang geblaat kort te houden: snelheid boven geheugen.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Op dinsdag 15 januari 2002 14:30 schreef TheDane het volgende:

[..]

nou, dat weet ik nog zo net niet ...
split() / explode() doen in feite niks anders dan checken of ze een bepaald karakter tegenkomen (en regex is over 't algemeen nog trager omdat ie ook nog eens de expressie moet evalueren)
dat is waar, maar dat heeft niets te maken met het feit of het in een array gezet wordt of niet... dat lijkt mij voor de snelheid niet (echt) interessant...

En het lijkt mij dat het evalueren van zo'n [class] == 'character' expressie niets anders doet dan voor alle characters uit die class nagaan of hij gelijk is aan dat character. Of je dat dan zelf code of dat het in een functie staat lijkt me niet echt uitmaken, wel?

* drm gaat even benchmarken...

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • TheDane
  • Registratie: Oktober 2000
  • Laatst online: 12:34

TheDane

1.618

Op dinsdag 15 januari 2002 14:36 schreef drm het volgende:

[..]

dat is waar, maar dat heeft niets te maken met het feit of het in een array gezet wordt of niet... dat lijkt mij voor de snelheid niet (echt) interessant...

En het lijkt mij dat het evalueren van zo'n [class] == 'character' expressie niets anders doet dan voor alle characters uit die class nagaan of hij gelijk is aan dat character. Of je dat dan zelf code of dat het in een functie staat lijkt me niet echt uitmaken, wel?

* drm gaat even benchmarken...
hmm, klopt wel wat je zegt, maar zoiets als regex is voor niet-complexe expressies beduidend langzamer dan voor complexe gevallen. (bijvoorbeeld strings in strings zoeken is met regex trager dan met substr() ,.

maargoed,.
ontopic: ik denk dat als je 250k aan tekst moet parsen/scannen, dat je dan toch wel rekening met enige doorlooptijd mag houden .. je kan imo niet verwachten dat je binnen 1 seconde 't aantal woorden te pakken hebt ...

misschien kun je tijdens 't lezen al tellen ,. scheelt ook weer denk ik

  • saryon2413
  • Registratie: December 2001
  • Laatst online: 09-12-2021
Op dinsdag 15 januari 2002 14:41 schreef TheDane het volgende:

[..]

hmm, klopt wel wat je zegt, maar zoiets als regex is voor niet-complexe expressies beduidend langzamer dan voor complexe gevallen. (bijvoorbeeld strings in strings zoeken is met regex trager dan met substr() ,.
klopt, maar in dit geval is ie sneller.
maargoed,.
ontopic: ik denk dat als je 250k aan tekst moet parsen/scannen, dat je dan toch wel rekening met enige doorlooptijd mag houden .. je kan imo niet verwachten dat je binnen 1 seconde 't aantal woorden te pakken hebt ...
eeeuhm......imo mag dat wel, want er zit niet voor niets
een p3 te werken.
een textje hoort dan echt niet veel moeite te kosten
om ff door te tellen. (gezien ik al een gigantische
snelheidswinst heb behaald ben ik tnt ook wel blij, MAAR
het kan bijna altijd beter (of altijd bijna beter?))
misschien kun je tijdens 't lezen al tellen ,. scheelt ook weer denk ik
dat gaat jammer genoeg niet: ik haal het hele zooitje uit
een database, die eerst gevuld was met een of meerdere textfiletjes.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

* drm heeft even een benchmarkje gedraaid en dit is het resultaat:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$count = count ( split ( "[^a-zA-Z]", $string ) );
--> Elapsed time:25.7049

$count = count ( explode ( " ", $string ) );
--> Elapsed time:0.092348

$count = count ( preg_split ( "/\W/", $string ) );
--> Elapsed time:0.45162

$count = 0
$length = strlen ( $string );
for ( $a = 0; 97768 < $length; $a++ )
   if ( $string [ $a ] == ' ' || $string [ $a ] == "\n" || $string [ $a ] == "\r" )
    $count++;
--> Elapsed time:2.229432

als je ff wacht zet ik ook nog een linkje online
(dit is offline @win98, pIII-500)

edit:
_______________________________________________
Dit is een UNIX-bak, ook 500mhz dacht ik... not sure...
Benchmark
Source v/d benchmark
het gebruikte textbestand (is btw. van het pixeltown topic in /13)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • saryon2413
  • Registratie: December 2001
  • Laatst online: 09-12-2021
bedankt iedereen.

heb in de database een kleine 60 html paginas gestopt,
en in totaal is ie nu 30 secondes bezig. inclusief
de tijd die nodig is om woordjes te tellen :)

en dat van 300-600 secondes, vind ik een hele leuke verbetering :9~

  • dusty
  • Registratie: Mei 2000
  • Laatst online: 21-02 00:06

dusty

Celebrate Life!

Op dinsdag 15 januari 2002 14:03 schreef MarcoTC het volgende:
Hoeveel woorden zijn dit?

"Jantje is 8 jaar.Morgen wordt ie 9."

8, 7 of 6?
5 >:)

getallen zijn geen woorden, hadden ze voluit geschreven moeten worden,
bovendien kan je jaar.Morgen als een woord tellen, aangezien de nederlandse spelling voorschrijft dat na een punt altijd een spatie hoort te komen. (of een nieuwe regel!)

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR

Pagina: 1