lib/test1.ex

defmodule Test1 do
  #import ExProf.Macro
  import Xpeg

  def performance do
   
    p =
      Xpeg.peg :json, dump_code: false, trace: false, dump_ir: false, dump_graph: true do
        # White space
        :s <- star({' ', '\t', '\r', '\n'})

        # Basic atoms
        true <- "true" * fn cs -> [true | cs] end
        false <- "false" * fn cs -> [false | cs] end
        :null <- "null" * fn cs -> [nil | cs] end

        # Parse strings - needs proper escaping for the capture
        :xdigit <- {'0'..'9', 'a'..'f', 'A'..'F'}
        :unicode_escape <- 'u' * :xdigit[4]
        :escape <- '\\' * ({'"', '\\', '/', 'b', 'f', 'n', 'r', 't'} | :unicode_escape)
        :string_body <- star(:escape) * star(+({'\x20'..'\x7f'} - {'"'} - {'\\'}) * star(:escape))
        :string <- '"' * str(:string_body) * '"'

        # Numbers are converted to Elixir float
        :minus <- '-'
        :int_part <- '0' | {'1'..'9'} * star({'0'..'9'})
        :fract_part <- "." * +{'0'..'9'}
        :exp_part <- {'e', 'E'} * opt({'+', '-'}) * +{'0'..'9'}

        :number <- float(opt(:minus) * :int_part * opt(:fract_part) * opt(:exp_part)) 

        # Objects are represented by an Elixir map
        :obj_pair <-
          :s * :string * :s * ":" * :value *
            fn [v, k, obj | cs] -> [Map.put(obj, k, v) | cs] end

        :object <-
          '{' *
            fn cs -> [%{} | cs] end *
            (:obj_pair * star("," * :obj_pair) | :s) *
            "}"

        # Arrays are represented by an Elixir list
        :array_elem <- :value * fn [v, a | cs] -> [[v | a] | cs] end

        :array <-
          "[" *
            fn cs -> [[] | cs] end *
            (:array_elem * star("," * :array_elem) | :s) * "]" *
            fn [a | cs] -> [Enum.reverse(a) | cs] end

        # All possible JSON values
        :value <- :s * (:number | :string | :object | :array | true | false | :null) * :s

        # The toplevel json document is a value with no other trailing characters
        :json <- :value * !1
      end

    s = File.read!("/tmp/json-32M")
    #s = to_charlist(s)

    #wap(fn ->
    #profile do
      s = Xpeg.match(p, s)
      s.time
    #end)
    #end
    
  end


  def run() do
    p =
      peg :dict, dump_ir: true, dump_code: false, trace: false, dump_graph: true do
        :dict <- 'a' | 'b' | 'c'
      end

    s = "abc"

    #s = to_charlist(s)

    #r = wap(fn ->
      match(p, s)
    #end)
    #r
  end

  def wap(code) do
    {:ok, pid} = Task.start(__MODULE__, :dump, [self, %{}])
    r = code.()
    Process.exit(pid, :kill)
    r
  end

  def wop() do

    wap do
      IO.inspect(a = 42)
    end

  end

  def compare() do
    s = File.read!("/tmp/json-32M")
    {t1, _} = :erlang.statistics(:runtime)
    a = Poison.decode!(s)
    {t2, _} = :erlang.statistics(:runtime)
    IO.puts("poison: #{(t2-t1)/1000}")
    
    {t1, _} = :erlang.statistics(:runtime)
    a = Jason.decode!(s)
    {t2, _} = :erlang.statistics(:runtime)
    IO.puts("jason: #{(t2-t1)/1000}")
  end

    

end