Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange behavior of to_lua with LPeg 0.12 #150

Closed
shmuz opened this issue Jun 26, 2014 · 17 comments
Closed

Strange behavior of to_lua with LPeg 0.12 #150

shmuz opened this issue Jun 26, 2014 · 17 comments

Comments

@shmuz
Copy link

shmuz commented Jun 26, 2014

[Windows XP SP3, MinGW, Lua 5.1, MoonScript 0.2.6]
The following test behaves OK with LPeg 0.10.2 but throws an error with LPeg 0.12

local to_lua = require("moonscript.base").to_lua
local function test()
  local t = os.clock()
  for k=1,50 do to_lua("5") end
  io.write(os.clock() - t, " ")
end
for k=1,5 do test() end

Output with LPeg 0.10.2:

0.156 0.157 0.156 0.156 0.156

Output with LPeg 0.12:

0.375 0.625 0.86 C:\Exe32\lua.EXE: s:/lua_share/moonscript\parse.lua:364:
rule '(a function)' undefined in given grammar
stack traceback:
        [C]: in function 'P'
        s:/lua_share/moonscript\parse.lua:364: in function 'build_grammar'
        s:/lua_share/moonscript\parse.lua:635: in function 'string'
        s:/lua_share/moonscript\base.lua:38: in function 'to_lua'
        test1.lua:4: in function 'test'
        test1.lua:7: in main chunk
        [C]: ?
@pygy
Copy link
Contributor

pygy commented Jun 26, 2014

As I pointed out on lua-l, this is lpeg 0.12 specific. Both LuLPeg (whose API derives from v0.12) and LPegLJ (which is a straight port of v0.12, now augmented for left recursion) work fine.

@shmuz
Copy link
Author

shmuz commented Jun 26, 2014

OK, but this renders LPeg 0.12 unusable for our application. In fact we have reverted today to LPeg 0.10.2.
BTW, I tried today LPegLJ, it worked fine but it was much slower than LPeg, and it is LuaJIT-only.

@pygy
Copy link
Contributor

pygy commented Jun 26, 2014

LPegLJ is usually faster than this. For parsing MoonScript, it is slower than LuLPeg with Lua 5.1... It is normally on par with LuLpeg + LuaJIT.

I've adapted your script to parse the MoonScript test suite:

package.loaded.lpeg=require((...))

local to_lua = require("moonscript.base").to_lua
local l = {}

for file in io.popen"ls /Users/pygy/src/moonscript/spec/inputs":read"*a":gmatch"%S+%.moon" do
  l[file]=io.open("/Users/pygy/src/moonscript/spec/inputs/"..file):read"*a"
end

local t = os.clock()
for _, v in pairs(l) do to_lua(v) end
print(os.clock() - t)
Lua LPeg time
Lua 5.1 LPeg 0.12 0.276622
LuaJIT LPeg 0.12 0.212588
LuaJIT LPegLJ 1.444692
Lua 5.1 LuLPeg 1.195138
Lua 5.2 LuLPeg 0.770269
LuaJIT LuLPeg 0.62903

LuaJIT 2.0 and 2.1 perform identically. If I'm not mistaken, LPeg 0.10 is faster than LPeg 0.12, but I don't have it at hand.

@shmuz
Copy link
Author

shmuz commented Jun 27, 2014

Many thanks for these interesting data!
At present I have no immediate need to replace our lpeg.dll (ver. 0.10.2) with another implementation.
What I would really want is fixing the problem in LPeg 0.12 (or at least confirmation that the problem exists). I'm not sure Roberto I. is aware of the problem. Maybe I should try to prepare a test case not involving MoonScript that demonstrates the problem and post it to lua-list.

@pygy
Copy link
Contributor

pygy commented Jun 27, 2014

A minimal test case would definitely help, debugging this based on the MoonScript parser may not be easy.

Do you already know what is going on?

BTW, out of curiosity, what kind of performance do you get with LPeg v0.10? Could you post your the local results of my benchmark with both v0.10 and 0.12?

@shmuz
Copy link
Author

shmuz commented Jun 27, 2014

No, I don't know what's going on.

BTW, I see you're not on Windows, could you confirm the issue with LPeg 0.12 on your system? With my original test, do you get increasing times and error like I do?

My local results:

Lua LPeg time
Lua 5.1 LPeg 0.10.2 0.266
Lua 5.1 LPeg 0.12 0.344
LuaJIT LPeg 0.10.2 0.141
LuaJIT LPeg 0.12 0.203

@pygy
Copy link
Contributor

pygy commented Jun 27, 2014

Yes, I can reproduce it in OS X. Same behavior exactly:

➜  ~  lua tmp/5.lua
lua: /usr/local/share/lua/5.1/moonscript/parse.lua:388: rule '(a function)' undefined in given grammar
stack traceback:
    [C]: in function 'P'
    /usr/local/share/lua/5.1/moonscript/parse.lua:388: in function 'build_grammar'
    /usr/local/share/lua/5.1/moonscript/parse.lua:659: in function 'string'
    /usr/local/share/lua/5.1/moonscript/base.lua:38: in function 'to_lua'
    tmp/5.lua:4: in function 'test'
    tmp/5.lua:7: in main chunk
    [C]: ?
0.894852 1.106658 1.588283 

Thanks for the numbers :-)

@zg0
Copy link

zg0 commented Jun 27, 2014

TTree::key overflows.

@pygy
Copy link
Contributor

pygy commented Jun 27, 2014

It is set in settoktable(), based on the length of various lua tables (ktable) that are merged during the creation of the parser.

I'm surprised it grows at parse time.

@leafo
Copy link
Owner

leafo commented Feb 28, 2015

Sorry for not responding. This has been a known issue for quite some time. It looks like the culprit is related to how the parser automatically generate non-terminals: http://lua-users.org/lists/lua-l/2015-02/msg00035.html

@zg0
Copy link

zg0 commented Feb 28, 2015

possible that this is not moonscript related problem. here http://lua-users.org/lists/lua-l/2015-02/msg00352.html I provided testcase without moonscript.

@leafo
Copy link
Owner

leafo commented Feb 28, 2015

Thanks for taking the time to look into it

leafo added a commit that referenced this issue Mar 1, 2015
@leafo
Copy link
Owner

leafo commented Mar 1, 2015

removing the cache for lpeg.V seems to fix all instances where I could reproduce problem.

@zg0
Copy link

zg0 commented Mar 3, 2015

eats ktable entries slowly, but stil crashes after ~7200 calls:

local to_lua = require("moonscript.parse").string
local function test(iteration)
local t = os.clock()
for k=1,50 do to_lua("5") end
io.write(iteration,":",os.clock() - t, " ")
end
for k=1,200 do test(k) end

for me its only lpeg problem.

@leafo
Copy link
Owner

leafo commented Mar 3, 2015

I agree it's an lpeg problem, but I should do the best I can to mitigate it until it's fixed.

@zg0
Copy link

zg0 commented Mar 5, 2015

with 0.12.2 0.2.6 and 0.3.0 versions works fine.

@leafo
Copy link
Owner

leafo commented Mar 5, 2015

great news :)

@leafo leafo closed this as completed Oct 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants