XML :: Twig: является ли parsefile () более эффективным, чем parse ()? - PullRequest
1 голос
/ 11 марта 2012

Я написал довольно простое веб-приложение на Perl, и оно обрабатывает XML-файлы, используя XML::Twig. Эти XML-файлы довольно большие и сложные, поэтому я намеренно использую переменную chunk by chunk, равную XML::Twig, а не метод «загрузить все сразу».

Однако, это веб-приложение полностью падает и умирает, если я загружаю большой XML-документ, даже при использовании метода чанкинга. Я не смог понять, почему это происходит, потому что веб-приложение размещено на общем сервере с 1and1.co.uk, и я не вижу файл журнала ошибок Apache. Даже когда я упаковывал вызовы в блок eval{}, я не мог уловить его от смерти. Досадно, что он отлично работает на моем сервере разработки дома, поэтому я не смог воспроизвести проблему.

Чтобы заставить его работать, я внес изменение, чтобы вместо использования метода parse() и передачи скаляра, содержащего весь XML, я записал XML в файл, а затем использовал parsefile( $filename ). Когда я внес это изменение, оно сработало.

Я просто немного озадачен этим, и я попытался с помощью чуда Google выяснить, действительно ли parsefile() более эффективен, чем parse(), но не смог ничего найти. Кто-нибудь знает?

Ответы [ 2 ]

2 голосов
/ 11 марта 2012

Посмотрите на источник.Это одно и то же.

В XML :: Twig parsefile - это просто расширенный XML::Parser::parsefile (суперкласс):

sub parsefile
  { my $t= shift;
    if( -f $_[0] && ! -s $_[0]) { return _checked_parse_result( undef, "empty file '$_[0]'"); }
    $t= eval { $t->SUPER::parsefile( @_); };
    return _checked_parse_result( $t, $@);
  }

В XML :: Parser , parsefile - это просто оболочка вокруг parse:

sub parsefile {
  my $self = shift;
  my $file = shift;
  local(*FILE);
  open(FILE, $file) or  croak "Couldn't open $file:\n$!";
  binmode(FILE);
  my @ret;
  my $ret;

  $self->{Base} = $file;

  if (wantarray) {
    eval {
      @ret = $self->parse(*FILE, @_);
    };
  }
  else {
    eval {
      $ret = $self->parse(*FILE, @_);
    };
  }
  my $err = $@;
  close(FILE);
  die $err if $err;

  return unless defined wantarray;
  return wantarray ? @ret : $ret;
}
0 голосов
/ 11 марта 2012

Я уверен, что 1 и 1 позволят вам получить доступ к файлу журнала Apache, так как это жизненно важный инструмент для отладки CGI и веб-приложений, таких как ваше.Побалуйте их и спросите, как это сделать.

Если ваши файлы XML имеют большой размер, это портит смысл использования XML::Twig в режиме чанков.Также вероятно, что ваше приложение не работает на сервере, поскольку оно превысило квоту памяти.Опять же, звонок в вашу веб-хостинговую компанию скажет вам, так ли это.

Как ваш XML попадает в память?Если вы записываете его в память из файла XML, просто оставьте исправление без изменений и получите XML::Twig для чтения непосредственно из файла.Если вы извлекаете XML из удаленного URL-адреса, помните, что XML::Twig имеет метод parseurl, который позволит избежать извлечения данных в локальный файл.Я не могу придумать другой вероятный источник, поэтому вам придется объяснить.

...