[pmwiki-users] speeding up pages and pagelists

Patrick R. Michaud pmichaud at pobox.com
Thu Jan 5 13:54:10 CST 2012

On Thu, Jan 05, 2012 at 11:51:24AM -0600, Frank Graffagnino wrote:
>  Our pmwiki site has pages that sometimes take between 2 - 8 seconds to
> load.  [...]
> enable the following in my local config:
> 1. With pagelist caching enabled, why is there an PageStore::ls for every
> single result?  Should that be in the cache?

PageStore::ls() returns a list of pages matching a pattern passed as an
argument.  PmWiki can't reliably cache the list of pages between page 
requests because external things are allowed to modify the files in
the pagestore directories, and the only way to find out that files have 
been added and deleted is by scanning the directories.

Within a single page request it might be possible for PmWiki to scan the
pagestore directories once and keep a list of everything it finds, but
for sites with lots of pages that could quickly eat up a fair bit of 
memory (and there's a bit of trickiness in that the pattern argument
may be different from one call to the next).  We could add it as an
option, I suppose.

> 2. Is the spike in CPU usage for each pageview normal?  Could something
> like PHP accelerator help?

It depends on the complexity of the pagelist request -- if there's a lot
of sorting or pattern matching going on, it could spike the CPU, yes.

> 3. I have EnableHtmlCache on, but it doesn't appear to do anything.  Is
> this because the pages require login?

Most likely, yes.  HTML caching is of little value when the contents
of a page can be affected by the identity and authorizations of the 
requesting party.

> 4. Is there anything I can do to get rid of all those PageStore::ls calls?

See above -- or perhaps Petko and/or I could work on a caching option here.

> 5. Is there anything I'm doing in my template that is ineffecient?

My guess is that it's the (:if:) markups that are eating up a lot of
CPU time.  Try switching

    (:if equal {<$Group}:)    -->   (:template first {=$Group}:)
    (:if equal {>$Group}:)    -->   (:template last {=$Group}:)

See "Page list template special markup" at 
http://www.pmwiki.org/wiki/PmWiki/PageListTemplates .

Using (:template ...:) instead of (:if:) *greatly* reduces the amount
of work the engine has to do to produce the pagelist.

Also, try really hard to move the logic of

   (:if [ exists {=$FullName} && auth read {=$FullName} ]:)

out of the template body and into the pagelist directive itself somehow.  
It's much more efficient to have pagelists exclude pages from formatting 
at the outset than it is to have an (:if:) directive remove the markup 
after it's already been processed.  As a first cut, you can try adding

    (:template defaults if="exists {=$FullName} && auth read {=$FullName}" :)

to the pagelist template and change the "(:if ... :)" directive to
"(:template each:)".  Or, you can put the if= directly into the pagelist
directive (see http://www.pmwiki.org/wiki/PmWiki/PageLists#pagelistif).

Try some of these suggestions and see if things improve sufficiently.
If they don't, let's analyze what you have left after making some of the
above changes and see where further refinements can be made.

In the final analysis, pagelists still remain fairly expensive.
We've looked at many ways to try to make things faster in specific cases,
but the overall consensus has typically been that we didn't want to
sacrifice too much flexibility in the process.


More information about the pmwiki-users mailing list