 |
intoK Apprentice
Joined: 18 Feb 2007 Posts: 190
|
Posted: Thu Oct 09, 2008 10:15 pm
support for write to list in record var |
another key functionality gone missing...
example:
#ADDK temp a {1|2|3}
#SHOWDB @temp
#SA %ismember(1,@temp.a)
#SA %iskey(@temp,a)
#ADDI temp.a 4
#SHOWDB @temp |
|
|
|
 |
intoK Apprentice
Joined: 18 Feb 2007 Posts: 190
|
Posted: Mon Oct 13, 2008 12:05 pm |
for anyone interested (i find it quite puzzling noone supported me on this yet!)
i found temporary workaround for this:
var.list=%dups(@var.list|newitem(s))
not pretty tho...
i really see no reason why this function of ADDI was omitted, especially since DELI works fine with those  |
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Mon Oct 13, 2008 1:48 pm |
This wasn't omitted, it was changed deliberately when data record variables and string variables were changed to use hashes rather than string values like they did previously. Because all the functions and commands that dealt with the old-style string lists needed to be updated to use hashes, it broke some compatability with string lists nested inside data record variables, because the system CMUD uses doesn't support hashes within hashes. So the string list isn't hashed, but CMUD expects it to be - therein lies the problem.
It's not insurmountable, though. This code will add an item to a string list inside a data record variable:
#addkey something test %additem("blah",@something.test)
This will remove duplicates like #additem does:
#addkey something test %dups(%additem("blah",@something.test))
It's possible to write a function to this for you. For example:
#function add_item {#if %4 {#addkey %1 %2 %additem(%3,%db(%1,%2))} {#addkey %1 %2 %dups(%additem(%3,%db(%1,%2)))}}
Which I haven't tested but which hopefully demonstrates the principle I'm talking about. |
|
|
|
 |
intoK Apprentice
Joined: 18 Feb 2007 Posts: 190
|
Posted: Mon Oct 13, 2008 2:23 pm |
aah, cheers for that... wo look into implementation its kinda hard to grasp, so it still puzzles me that #deli works, shouldnt it fail in the circumstances expecting value to be a hash?
anyway, im sure this is easly workable withing #ADDI code to decide on method based on target.
your code is more proper, but even longer to write i was thinking about the function, but im worried about performance impact
also, i understand that since string lists in records arent hashed, but operations demand them to be, there must be transcription of every access, so compatibility code is there... also this design massively impacts on performance, since string is transcribed before every access!? serious design flaw  |
|
|
|
 |
Fang Xianfu GURU

Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Mon Oct 13, 2008 2:29 pm |
I don't know anything about the underlying code, I just know that the hashing we have is faster than no hashing at all :P
If you're that concerned about the performance impact, you should really stop using nested string lists - they're pretty slow because, like I say, they're not hashed. It's much better to use a stringlist on its own or perhaps even the keys of a data record variable, depending on what you're using it for.
You might get some mileage out of using Lua rather than zScript, because you can build much more complex data structures in Lua. |
|
|
|
 |
intoK Apprentice
Joined: 18 Feb 2007 Posts: 190
|
Posted: Mon Oct 13, 2008 2:52 pm |
i really dont fancy trillion of variables littering my settings, but i might yet come around it
lua is fine language, but it needs a lot of writting for little result for an interpreter, also how much 150kb of uncompressed x86 code handling infinite data structures and having quite a bit of fancy functions can be optimized for speed  |
|
|
|
 |
intoK Apprentice
Joined: 18 Feb 2007 Posts: 190
|
Posted: Mon Oct 13, 2008 4:27 pm |
well, it appears either string lists arent hashed at all or string lists in records are hashed as well, i see no performance difference in any case
#AL t10k {$a=@timesz;#LOO 10000 {#EXE %-1};#SA 10k: (@timesz-$a)}
#VARF timesz {%eval(%time(s)*1000+%time(z))}
#VA tmp.abc {212|237|29|6|86|8|465|33|254|1|65|39|98}
t10k #no %ismember(86,@tmp.abc)
#VA tmp {212|237|29|6|86|8|465|33|254|1|65|39|98}
t10k #no %ismember(86,@tmp)
t10k #no %ismember(86,"212|237|29|6|86|8|465|33|254|1|65|39|98")
all goes around 3.3s for me
edit: same results for %numitems, which should be super blitz has it been hashed...
edit2: i just bothered to check for zmud, its twice faster... im getting depressed now |
|
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Oct 13, 2008 4:49 pm |
You need to mark a variable as a "stringlist" type for the hashing to work. Doing:
#VA tmp {212|237|29|6|86|8|465|33|254|1|65|39|98}
just makes tmp a normal string variable (or autotype) in most cases. You can do "#VAR tmp" to display the variable along with the type. If you create a string list using #ADDITEM then it gets marked as a string list (other commands and functions might also mark it as a string list).
Also, the %ismember function only uses faster searching when the string list is sorted. So you need to do a "#SORT tmp" before using %ismember to do a search. Otherwise CMUD uses a linear search instead of a binary search. |
|
|
|
 |
intoK Apprentice
Joined: 18 Feb 2007 Posts: 190
|
Posted: Mon Oct 13, 2008 4:55 pm |
uuh, cheers! this should all be in documentation btw, i got cracked for an hour figuring why my functions dont work, documentation states #RET while it needs #RETU
edit: im getting same results irregardles?!
Variable: + tmp (StringList) 1|212|237|254|29|33|39|465|6|65|8|86|98
10k: 3266
Variable: + tmp (Literal) 1|212|237|254|29|33|39|465|6|65|8|86|98
10k: 3172
Variable: + tmp (Literal) 212|237|29|6|86|8|465|33|254|1|65|39|98
10k: 3312 |
|
|
|
 |
|
|
|