LUA is the toy language for those who enjoy the Forced Flushing Of L1/L2 Cache per operation. In fact, every operation causes several L2 cache misses during table look-ups, flushing both the L1 and L2 caches.
>>2
It'll never compare to other languages that are data-oriented and data-parallel friendly, like your old school imperative languages such as C, C++, or functional languages like Scala or F#.
LuaJIT and Lua/LLVM still using those god damn look-up tables in the JITed code.
Your idea of ``FAST AS VIRGIN FUCK'' is incorrect, as Lua is no longer a virgin, but rather a two-time whore who can't even find anyone willing to pay her $5 for a blowjob.
Yeah. A report by Microsoft about a Non-microsoft product. What exactly did you expect, a fair competition?
Besides me not even attempting to argue that Lua does indeed stated Table cache ``faults'' (if peanuts like that can even be called a fault to begin with), it's obvious that
1.) Microsoft always makes even the least terrible fault look like a fucking drama
2.) I have yet to read about a case where this fault actually causes any noticable trouble
So please take your rant and go to /g/, where you belong to.
Yeah. A report by Microsoft about a Non-microsoft product. What exactly did you expect, a fair competition?
Besides me not even attempting to argue that Lua does indeed stated Table cache ``faults'' (if peanuts like that can even be called a fault to begin with), it's obvious that
1.) Microsoft always makes even the least terrible fault look like a fucking drama
2.) I have yet to read about a case where this fault actually causes any noticable trouble
So please take your rant and go to /g/, where you belong to.
Name:
Anonymous2011-02-05 9:32
>>5-6
You are wrong. Memory hazards and cache misses are the primary reason for slow software on modern hardware. Optimising for cache coherent hardware can reap performance gains of several orders of magnitudes. This is no laughing matter.
Mad that Microsoft has some smart developers working there? Fine, here's one from Sony for PS3/Cell development showing how important programming for cache efficiency really is.
Lua is the anti-thesis of data-oriented programming. Lua is a laughing matter. FFOC indeed.
Name:
Anonymous2011-02-05 9:38
>>7
I was asking for a case where this matters. A case that can actually be tracked down.
While in theory I'd fully agree with you, your point is pretty much a pointless one if you're entirely unable to actually prove it.
Judging by your logic, an application that is entirely written in an interpreted language (such as eve online, which is almost entirely written in Python), must be OMG FUCKING SLOW.
But how come it isn't at all? Good question indeed. Your turn.
Name:
Anonymous2011-02-05 9:44
>>8
Python does not use huge sprawling look-up tables for all object-name resolution lookups. CPython does have scalability issues due to the GIL, but this isn't a problem with IronPython or rewrites of Python targeting LLVM.
Lua's tables are deeply ingrained into the language. There's no correcting it.
>>1
That explains a lot. I was playing a puzzlequest game on the DS and it was amazingly slow. I couldn't rationalize it. It's written in Lua in no small part, and now that I know this it all makes sense.
>>5 Table cache ``faults'' (if peanuts like that can even be called a fault to begin with)
But... they are faults, by their very definiIHBT and how!
Name:
Anonymous2011-02-05 9:46
>>8
Does Eve run on consoles? Nope. I know the folks working on Batman Arhkam Asylum originally were using Lua for scripting, but performance issues forced them to rewrite all of their scripts in native C++ so that they could ship it on current generation consoles.
Name:
Anonymous2011-02-05 9:54
>>11 I know the folks working on Batman Arhkam Asylum originally were using Lua for scripting [citation needed]
>>14
Because what's a couple of orders of magnitude between friends? 1ms per frame or 100ms per frame, who cares, except console gay developers who are all crazy?
Name:
Anonymous2011-02-05 10:52
>>15
I think >>14 was in support of the fact that cache-conscious code is important. He did after all say he had a point. He was just pointing out the exaggeration.
That said, performance improvements of hundreds of times is a big deal.
If you don't understand the memory model of your computational hardware, you will never be able to develop fast software for it.
Etymology From Proto-Oceanic (compare Malay luah).
Verb lua
1. to vomit
Name:
Anonymous2011-02-07 8:25
Lua's problem is that it uses hash tables for dispatching. This limits Lua to single dispatch in addition to making everything slow and rigid. You cant redefine `+` in Lua, as I do in my Lisp DSL
`+` a:Num b:Str -> "$a$b"
`+` a:Str b:Num -> "$a$b"
neither you can union two types
userFriendly? x:string? -> ye
userFriendly? x:picture? -> ye
Name:
Anonymous2011-02-07 8:28
And of course Lua doesnt have Lisp macros, which are very nice to have, especially when entering arbitrary complex game logic.
>>24
Your ``in Lisp'' DSL is just Perl 6 with a lisp and ML/Haskell syntax:
Operator overloading (Perl 6 does it better)
Lisp macros (Perl 6 does it worse(?))
Multidispatch
Pattern matching
$ Num and Str SYNTAX. SYNTAX EVERYWHERE
In conclusion: WHBTC
Name:
Anonymous2011-02-07 9:01
>>25
>Operator overloading (Perl 6 does it better)
You wrong. DSL doesnt do operator overloading. It does pattern matching. That is: I can write
hasUserFriendlyObject [@_ x:userFriendly? @xs] -> [x xs]
meaning find first `userFriendly?` object, then return it and rest of the list. Doubt that Perl does this.
>>39 So, you cant? Q.E.D.
sub faggot (@xs) { drop_while(@xs, { not userfriendly($^a) }) } # it assumes the existence of drop_while. Its implementation would be trivial anyway.
>>44 multi sub faggot ($n) { "oh god how did i get here im not good with computers"}
faggot multi sub faggot ("HAX MY") { "ANUS!" }
faggot multi sub faggot ("I'm >>44 and love cocks") { "You are!" }
faggot faggot("I'm >>44 and love cocks")
You are! faggot("HAX MY")
ANUS! faggot("sjdjksda")
oh god how did i get here im not good with computers
Name:
Anonymous2011-02-07 9:35
>>48
Because: Lua's creators also state that Lisp and Scheme with their single, ubiquitous data structure mechanism (the list) were a major influence on their decision to develop the table as the primary data structure of Lua.
>>49
faggot _ -> "oh god how did i get here im not good with computers"
1.faggot "HAX MY" -> "ANUS!"
2.faggot "I'm >>49 and love cocks" -> "You are!"
code less, create more
>>57
The ``in Lisp'' DSL contains an ad hoc, informally-specified, bug-ridden, slow and unnecessary implementation of half of Perl 6, Haskell and ML on top of the already perfect LISP.
Doesn't Lua's JIT assume that the mostly-read tables (such as _G) remain read-only until the JIT is explicitly told they have been modified (via a `check your damn assumptions' flag)? I don't feel like reading its sauce right nao, but I would guess its author would have been smart enough not to execute an entire damn hash table lookup at almost every VM cycle.
>>69
Consoles forbid code-as-data, because this would allows to leave a backdoor for hackers. I heard Micro$ucks and Intel promise forbidding executing unsigned code even on PC platform, so to write code you will have to buy a developer's license from Intel.
Name:
Anonymous2011-02-07 10:29
>>72
Lost freedom - this is what you get for stealing jewish money by pirating movies, music and games.
>>76
``Aye cant run my krakkid myspacetunesbook 12.3 :((( y????''
``ur patch 2 pirate nfs mmfsq dusent run animore D= y???''
``my computar is broken it dont go well on nero 12 burning rom anymore >.>''
``hi i want 2 become an hax0r how do i compile my codes thx everybody''
``hi i tried to compile my c code liek in random tutorial but it doesnt run it sais itz not signed what does iet mean how do i signed it? heres the code goto-filled simple C commandline calculator that can do one operation at time plz halp?????''
>>79
Technical support will shoot themselves within hours.
Name:
Anonymous2011-02-07 11:00
>>79
Normal people never compile code. They buy code in those big lame boxes or in web shops, like this Steam. Even better, they run code on a cloud computing service. Now you can even play Crysis as a service from remote server.
>>82
Normal people: ``Aye cant run my krakkid myspacetunesbook 12.3 :((( y????''
``ur patch 2 pirate nfs mmfsq dusent run animore D= y???''
``my computar is broken it dont go well on nero 12 burning rom anymore >.>''
Proof that people like: ``hi i want 2 become an hax0r how do i compile my codes thx everybody''
``hi i want 2 become an hax0r how do i compile my codes thx everybody''
exist: http://ubuntuforums.org/forumdisplay.php?f=39
>>21
Your ``Lisp'' DSL what? Does it compact lists into lists of 128-byte arrays to fit its shit into 128 bytes? Did you even test it with major CL implementations for L1/L2 usage?
If not, go back to your LISP threads where you can freely continue to ignore requests for source code of your pile of syntax.
>>87 where you can freely continue to ignore requests for source code of your pile of syntax. I LOVE YOU!I LOVE YOUR POST!I READ IT FIVE TIMES!KEEP POSTING!
Name:
Anonymous2011-02-07 12:06
>>87
If you care about bytes, you should write assembly.
A Lisp programmer knows the value of everything, but the cost of nothing. — Alan Perlis
Richman Stallmont: Die Python! You don't belong in this world!
FIOCula: It was not by my hand I am once again given FIOC. I was called here by GvR who wish to pay me whitespaces.
Richman Stallmont: Whitespaces? You steal men's indentation, and make them your slaves!
FIOCula: Perhaps the same could be said of all languages.
Richman Stallmont: Your words are as forced as your indentation! Lispers ill-need a savior such as you!
FIOCula: What is a Lisp? A miserable little pile of parentheses! But enough talk... Have at you!
>>87 Does it compact lists into lists of 128-byte arrays
Actually it uses 64-byte arrays for small lists and normal array indexing to access object fields. So I dont see any fundamental problems for efficiency.
>>99
That's not what I meant to say, you're a monster, you destroy the child cudders' dream to cons up and become a valid evaluable argument list and live happy being applied to the procedure till its garbage collection by deviating him to be a dirty AIDS-ridden drug-addicted no life array of int64s. You have no heart, how can you call yourself a Lisper, if you're so insensible to cudders‽‽
Name:
Anonymous2011-02-07 15:57
>>99
>immutable
This wont lead to loss of efficiency, as ususual Lisp coding style on lists is map@reducing them.
Name:
Anonymous2011-02-07 16:03
>>100
Cons-pairs are obsolete. Love how Clojure dealt with them. Rich is a genius!
>>108
Clojure has nomads[1], everything that implements in some way monads and makes it available to everyone in some standard way (clojure-contrib) will never become future nor mainstream.
>>110
Clojure has unhygienic macros. Unhygienicunhygienicunhygienicunhygienic. b]U[/b]nhygienicmacrosin 2011‽ Do I still need to worry about not shadowing my macro's symbols? Maybe prepend my function name with org.clojure.core/list or shit like that.
>>117
With some other macros:
(define-syntax-case (aif p t f)
(with-literal stx (it) ; stx is unhygienic, contains the called syntax.
#'(let ((it p))
(if it t f))))
>>119 overuse of object oriented (OOP) constructs >>117-118 doesn't use OOP. incorrect usage of design patterns >>117-118 doesn't use any design pattern. overuse of OOP methods/functions/procedures >>117-118 uses only the strict necessary. declarative programming >>117-118 does the same as >>114, if one it's considered bloated for this, the other will be too. excessive loop unrolling >>117-118 doesn't even use loops. excessive use of multiple conditional If statements
See: declarative programming. It also uses just one if. dead code
All the code is reachable. redundant calculations
`it' is evaluated once.
So, you started whining about something you don't even know? Perfect.
(defmacro aif (p t f)
`(let ((it ,p))
(if it ,t ,f)))
; later...
(defun if (x) x)
(aif (if 2) it 3) ; expands to: (let ((it (if 2))) (if it it 3))
; but now if it's being shadowed by if!!!
; it doesn't work
(define-macro (aif p t f)
#:capture it
#'(let ((it p))
(if it t f)))
; later...
(define (if x) x)
(aif (if 2) it 3)
; this expands to (let ((it (if 2))) (the-old-if it it 3))
; OMG IT WERKZ!!
; `if' it's just looked up in the scope of the macro definition!!
Name:
Anonymous2011-02-07 19:37
>>134
>(defun if (x) x)
But my `if` resides in package cl-user, and `aif` uses `if` from CL! I guess crappy academic Scheme just doesnt have packages, like CL and Clojure do.
Name:
ve seen it before!!112011-02-07 19:40
hygienic
Sometimes, you’re on a team, and you’re busy banging out the code, and somebody comes up to your desk, coffee mug in hand, and starts rattling on about how if you use multi-threaded COM apartments, your app will be 34% sparklier, and it’s not even that hard, because he’s written a bunch of templates, and all you have to do is multiply-inherit from 17 of his templates, each taking an average of 4 arguments, and you barely even have to write the body of the function. It’s just a gigantic list of multiple-inheritance from different classes and hey, presto, multi-apartment threaded COM. And your eyes are swimming, and you have no friggin’ idea what this frigtard is talking about, but he just won’t go away, and even if he does go away, he’s just going back into his office to write more of his clever classes constructed entirely from multiple inheritance from templates, without a single implementation body at all, and it’s going to crash like crazy and you’re going to get paged at night to come in and try to figure it out because he’ll be at some goddamn “Design Patterns” meetup.
>>136
If he's writing code that he expects you to use but that code doesn't match the design spec, just tell him you're not going to bother with it until the spec is updated.
>>135 I guess crappy academic Scheme just doesnt have packages
It has But my `if` resides in package cl-user, and `aif` uses `if` from CL!
Enjoy your name clashes and gensyms, ``faggot''.
LuaJIT and Lua/LLVM still using those god damn look-up tables in the JITed code.
The table look up certainly isn't ideal, compared to indexing into an organized location within a struct, but it isn't that bad. Strings in lua are interned into a symbol table, which means that all strings with equal contents are actually the same string, starting at the same memory address. Because of this, using strings as keys in a hash table in lua is as efficient as using pointers as keys. Also, many class-like and struct-like tables in lua don't usually have that many fields, maybe 12 or 15 at the max, unless of course there is a massive amount of inheritance going on. Any more and it wouldn't be easy for a programmer to follow the code. A typical hash table using some type of probing scheme will usually keeps it's array length around twice as much as there are objects in it, yielding structs that are around twice as large as they normally would be. This a cost, but it isn't that bad. Lua is a simple language, and typically out performs other interpreted languages. It's flaws aren't in speed. You can certainly criticize it for not having any support for threads, and having a pretty limited standard library. You can't even do a chdir without extending it with C, and there isn't built in support for real regular expressions, which is a little baffling for me since it is a scripting language and regex is usually their niche.
yeah me too. I'm sure developers using it in games would really appreciate it. It wouldn't require very much deviation from the language either, in fact, it might be implementable as is with some crazy hacks. Because nothing can actually be stored within a struct, just references to other values, a struct with n fields of arbitrary types can be implemented as a lua table using only the indecies, 1 .. n as keys. Doing this would ensure that it would look like a regular array under the hood. Then you could have table mapping field names to positions within the array:
apple_struct_field_locations = {num_seeds = 1,
color = 2,
age = 3}
and then, somehow have lua locate every point in your code where an apple_struct is being indexed by one of the three constant keys above, and inline replace it:
And since it's closedsource, there's a very good chance it's just vanilla Lua with some minor internal changes, like name, file extensions, maybe even changes in the bytecode generator.
But hardly anything that could possibly classify as ``better''.
Name:
Anonymous2011-09-24 19:21
why don't they just get an L3 cache on the XBox? :/
Name:
Anonymous2011-09-24 19:22
I'm guessing poor Lua performance comes from guys who don't understand how lexical closures work and so make hash tables for every persistent bit of data.
Poor perforamnce is caused by cretins who write inelegant bullshit, not languages.
>>150
Lexical closures still require more space per slot than a properly-packed zomg-optimized structure. Just saying, I'm an avid defender of closures but I don't find that they are a proper replacement for structs.
Name:
Anonymous2011-09-24 22:14
>>154
but they don't cause a cache miss every line like self.foo does.
function make_value(v)
return function() return v end,
function(new_v) v = new_v end
end
function make_struct(...)
local functions = {}
for i,v in ipairs({...}) do
getter, setter = make_value(v)
table.insert(functions, getter)
table.insert(functions, setter)
end
return unpack(functions)
end
function main()
local get_name, set_name,
get_age, set_age,
get_gender, set_gender = make_struct('John', 34, 'male')
print(get_name()) --> prints John
print(get_age()) --> prints 34
set_age(56)
print(get_age()) --> prints 56
end
Well, nil never appears as a value in ..., and the only keys are the integer indecies of the arguments, but there is a serious problem in that if the user calls the function with nil values in the arguments, then ... will only go up to the first nil argument and stop, cutting the arguments short. This can be solved by using a different value than nil to represent nil, although this is very inconvenient. If Lua didn't have this problem with ..., the hack wouldn't be necessary.
#!/usr/bin/lua
function make_value(v)
return function() return v end,
function(new_v) v = new_v end
end
struct_nil = {}
function make_struct(...)
local functions = {}
for i,v in ipairs({...}) do
local getter, setter
if v == struct_nil then
getter, setter = make_value(nil)
else
getter, setter = make_value(v)
end
table.insert(functions, getter)
table.insert(functions, setter)
end
return unpack(functions)
end
function main()
local get_name, set_name,
get_age, set_age,
get_gender, set_gender = make_struct('John', struct_nil, 'male')
print(get_name()) --> prints John
print(get_age()) --> prints nil
set_age(56)
print(get_age()) --> prints 56
end
main()
This is really irritating though, because if you wanted to create a struct using the return values of functions that may return nil, you'll have to compose the function with one that checks for nil values.
function struct_feild(v)
if v == nil then
return struct_nil
else
return v
end
end
person = {make_struct('John', 45, 'male', struct_field(get_other_guy_address()))}
So now if other_guy is homeless and doesn't have an address, it wont crash out the person struct, and person will also not have an address. (if you are wondering why there are { } around the make_struct call, putting a function call inside of an array will collect the multiple return values in the array).
I was going to do it again in scheme, but the multiple return value semantics in scheme are so complicated that it is more convenient to just store your structs as arrays and make your own getters and setters:
(define (make-person name age gender)
(vector name age gender))
correction: Lua only went up to before the first nil in ... because I was using ipairs({...}). If I had used pairs({...}), then it would have gotten the other non nil arguments. This is still problematic though, because it never makes a getter or a setter function for the nil arguments.
>>162 This can be solved by using a different value than nil to represent nil, although this is very inconvenient. If Lua didn't have this problem with ..., the hack wouldn't be necessary.
local function apairs (...)
local n = select("#", ...)
return function (t, i)
if i < n then return i + 1, t[i + 1] end
end, { ... }, 0
end
for i, v in apairs(10, 20, nil, nil, 50, nil) do
print(i, v)
end