#!/usr/bin/perl

use 5.010;
use utf8;
use warnings;
use strict;
use YAML;
use MARC::Moose::Record;
use MARC::Moose::Parser::Marcxml;
use MARC::Moose::Parser::MarcxmlSax;
use MARC::File::XML;

use Time::HiRes qw(gettimeofday);

binmode(STDOUT, ':encoding(utf8)');

my $raw_xml = <<EOS;
<record>
  <leader>00675cam a22002051  4500</leader>
  <controlfield tag="001">   10026159 </controlfield>
  <controlfield tag="003">DLC</controlfield>
  <controlfield tag="005">20050815184409.0</controlfield>
  <controlfield tag="008">830916s1910    gw            000 0 ger  </controlfield>
  <datafield tag="010" ind1=" " ind2=" ">
    <subfield code="a">   10026159 </subfield>
  </datafield>
  <datafield tag="035" ind1=" " ind2=" ">
    <subfield code="a">(OCoLC)9914473</subfield>
  </datafield>
  <datafield tag="040" ind1=" " ind2=" ">
    <subfield code="a">DLC</subfield>
    <subfield code="c">OCU</subfield>
    <subfield code="d">OCU</subfield>
    <subfield code="d">DLC</subfield>
  </datafield>
  <datafield tag="042" ind1=" " ind2=" ">
    <subfield code="a">premarc</subfield>
  </datafield>
  <datafield tag="050" ind1="0" ind2="0">
    <subfield code="a">PA6792.Z9</subfield>
    <subfield code="b">G4</subfield>
  </datafield>
  <datafield tag="100" ind1="1" ind2=" ">
    <subfield code="a">Germann, Peter.</subfield>
  </datafield>
  <datafield tag="245" ind1="1" ind2="4">
    <subfield code="a">Die sogenannten Sententiae Varronis.</subfield>
    <subfield code="c">Von Peter Germann.</subfield>
  </datafield>
  <datafield tag="260" ind1=" " ind2=" ">
    <subfield code="a">Paderborn,</subfield>
    <subfield code="b">F. Schöningh,</subfield>
    <subfield code="c">1910.</subfield>
  </datafield>
  <datafield tag="300" ind1=" " ind2=" ">
    <subfield code="a">2 p. l., 98 p., 1 l.</subfield>
    <subfield code="c">24 cm.</subfield>
  </datafield>
  <datafield tag="440" ind1=" " ind2="0">
    <subfield code="a">Studien zur Geschichte und Kultur des Altertums ...</subfield>
    <subfield code="v">3. Bd., 6. Hft</subfield>
  </datafield>
  <datafield tag="600" ind1="1" ind2="0">
    <subfield code="a">Varro, Marcus Terentius.</subfield>
    <subfield code="k">Spurious and doubtful works.</subfield>
    <subfield code="t">Sententiae Varronis.</subfield>
  </datafield>
</record>
EOS

my $raw_json = '{"leader":"00675cam a22002051  4500","fields":["001","   10026159 ","003","DLC","005","20050815184409.0","008","830916s1910    gw            000 0 ger  ","010",{"subfields":["a","   10026159 "],"ind1":" ","ind2":" "},"035",{"subfields":["a","(OCoLC)9914473"],"ind1":" ","ind2":" "},"040",{"subfields":["a","DLC","c","OCU","d","OCU","d","DLC"],"ind1":" ","ind2":" "},"042",{"subfields":["a","premarc"],"ind1":" ","ind2":" "},"050",{"subfields":["a","PA6792.Z9","b","G4"],"ind1":"","ind2":""},"100",{"subfields":["a","Germann, Peter."],"ind1":"1","ind2":" "},"245",{"subfields":["a","Die sogenannten Sententiae Varronis.","c","Von Peter Germann."],"ind1":"1","ind2":"4"},"260",{"subfields":["a","Paderborn,","b","F. Schöningh,","c","1910."],"ind1":" ","ind2":" "},"300",{"subfields":["a","2 p. l., 98 p., 1 l.","c","24 cm."],"ind1":" ","ind2":" "},"440",{"subfields":["a","Studien zur Geschichte und Kultur des Altertums ...","v","3. Bd., 6. Hft"],"ind1":" ","ind2":""},"600",{"subfields":["a","Varro, Marcus Terentius.","k","Spurious and doubtful works.","t","Sententiae Varronis."],"ind1":"1","ind2":""}]}';

# Number of time the above record is parsed
my $max = 1000;

# Tested SAX parsers
my @xml_parsers = qw(
    XML::LibXML::SAX::Parser
    XML::SAX::Expat
    XML::SAX::ExpatXS
);


sub parse_with_marc_moose {
    my $parser = MARC::Moose::Parser::Marcxml->new();
    my $start = gettimeofday;
    for ( my $count = 0; $count < $max; $count++ ) {
        my $record = $parser->parse( $raw_xml );
    }
    print "Parsed $max records from XML using MARC::Moose (pure Perl): ",
          gettimeofday - $start, "\n";
}


sub parse_with_marc_moose_sax {
    for my $sax_parser ( @xml_parsers ) {
        $XML::SAX::ParserPackage = $sax_parser;
        my $parser = MARC::Moose::Parser::MarcxmlSax->new();
        my $start = gettimeofday;
        for ( my $count = 0; $count < $max; $count++ ) {
            my $record = $parser->parse( $raw_xml );
        }
        print "Parsed $max records from XML using MARC::Moose and ",
              "$sax_parser : ", gettimeofday - $start, "\n";
    }
}


sub parse_with_marc {
    for my $sax_parser ( @xml_parsers ) {
        $XML::SAX::ParserPackage = $sax_parser;
        my $count = 0;
        my $start = gettimeofday;
        for ( my $count = 0; $count < $max; $count++ ) {
            my $record = MARC::Record->new_from_xml( $raw_xml );
            $count++;
            last if $count == $max;
        }
        print "Parsed $max records from XML using MARC and ",
              "$sax_parser : ", gettimeofday - $start, "\n";
    }
}


sub json_parse_with_marc_moose {
    my $count = 0;
    my $start = gettimeofday;
    for ( my $count = 0; $count < $max; $count++ ) {
        my $record = MARC::Moose::Record::new_from( $raw_json, 'json' );
        $count++;
        last if $count == $max;
    }
    print "Parsed $max records from JSON using MARC::Moose : ",
          gettimeofday - $start, "\n";
}   


json_parse_with_marc_moose();
parse_with_marc_moose();
parse_with_marc_moose_sax();
parse_with_marc();

