r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

Endo
13-Oct-2011
[2435]
There is a huge speed difference: (my benchmark function executes 
given block 1'000'000 times)
>> i: 0 benchmark [i: i + 1]
== 0:00:00.25
>> i: 0 benchmark [++ i]
== 0:00:02.578
Geomol
13-Oct-2011
[2436x4]
That's more the difference between a native and a mezzanine, than 
the method.
Related is using POKE on e.g. time!:

>> t: 10:20:30
== 10:20:30
>> poke t 2 42
== 10:42:30
>> t
== 10:20:30

But we can change a time using a set-path!:

>> t/2: 42
== 42
>> t
== 10:42:30

So the set-path! way doesn't do the same as POKE in this case.
That was in R2. In R3, POKE can't handle time!
And that's probably an ok decision.
Endo
13-Oct-2011
[2440]
That's more the difference between a native and a mezzanine, than 
the method.
 - That's right.
Geomol
13-Oct-2011
[2441]
From R3, where ++ is native::

>> dt [loop 10000000 [i: i + 1]]
== 0:00:01.90374
>> dt [loop 10000000 [++ i]]
== 0:00:01.011743
BrianH
13-Oct-2011
[2442]
Try it in R3:
>> dt [i: 0 loop 1000 [i: i + 1]]
== 0:00:00.000251
>> dt [i: 0 loop 1000 [++ i]]
== 0:00:00.000383


Then the difference is more due to the code in ++ to tell whether 
i is an integer or a series
Geomol
13-Oct-2011
[2443]
Hm, try do more loops on your system, Brian.
BrianH
13-Oct-2011
[2444x3]
Weirdly enough, I think that it might be faster sometimes depending 
on what is going on in the background.
Nope, consistently faster. No interpreter overhead.
>> dt [i: 0 loop 100000 [i: i + 1]]
== 0:00:00.041421
>> dt [i: 0 loop 100000 [++ i]]
== 0:00:00.022857
>> dt [i: 0 loop 1000000 [i: i + 1]]
== 0:00:00.205488
>> dt [i: 0 loop 1000000 [++ i]]
== 0:00:00.130813
Geomol
13-Oct-2011
[2447x2]
Yes, ++ is faster, contrary to your first test.
And it makes sense.
BrianH
13-Oct-2011
[2449]
The ++ and -- functions are in R2 for convenience and compatibility, 
not for speed.
Ladislav
13-Oct-2011
[2450]
++ is native in R3
Geomol
13-Oct-2011
[2451]
yes and yes
BrianH
13-Oct-2011
[2452]
Still, I made them as fast as I could while still being compatible.
Geomol
13-Oct-2011
[2453]
So we would expect things like

	next 'series

to be faster aswell than

	series: next series
BrianH
13-Oct-2011
[2454]
But not as useful. The current NEXT can operate on values returned 
from functions, or series referred to by protected variables.
Geomol
13-Oct-2011
[2455]
My suggested NEXT can do that also. I just suggest adding the possibility 
to call those with call-by-word.
Ladislav
13-Oct-2011
[2456x3]
NEXT cannot do it
It does not have that kind of argument evaluation
You would need to change the argument evaluation standard for it
BrianH
13-Oct-2011
[2459x2]
Geomol, if you change NEXT to call-by-word then in order to have 
it work on the results of a function you will need to assign those 
results to a temporary word, then in a separate statement run the 
NEXT. No more chaining.
If you try to support both then you lose the ability of NEXT to trigger 
an error if it is passed a word by accident, a valuable debugging 
aid.
Geomol
13-Oct-2011
[2461x2]
:)
I didn't suggest changing NEXT to call-by-word. I suggest adding 
that possibility beside its current behaviour.
Ladislav
13-Oct-2011
[2463]
Do you happen to know how?
Geomol
13-Oct-2011
[2464x2]
>> f: func [v] [either word? v [get v] [v]]
>> f 1
== 1
>> a: 2
== 2
>> f 'a
== 2
That's the thought.
BrianH
13-Oct-2011
[2466]
Yeah, that will make NEXT cause unintentional side effects instead 
of triggering errors. Does it have side effects or not? Who knows?
Ladislav
13-Oct-2011
[2467]
aha, so you are suggesting to just accept word as yet another type 
of argument, i.e. to support NEXT 'A
Geomol
13-Oct-2011
[2468x2]
yes
Mezzanine example:


>> my-next: func [series] [either word? series [set series next get 
series] [next series]]
>> my-next [a b c]
== [b c]
>> block: [a b c]
== [a b c]
>> my-next 'block
== [b c]
>> block
== [b c]
Ladislav
13-Oct-2011
[2470]
Anyway, it does not look like a best idea to me. Besides, in the 
case of ++ a new (special) function with a different argument passing 
convention was defined
Endo
13-Oct-2011
[2471]
We talked about to change the value of non-series values by this 
way:
>> a: 5
>> multiply 'a 5
>> ? a
== 25


But ofcourse we are not sure about performance overhead or possible 
other problems.
Geomol
13-Oct-2011
[2472x3]
I've been thinking about this before, and there was a discussion 
on Carl's blog long time ago. It came to me again, when I looked 
at LOWERCASE and UPPERCASE. They work on strings, and does change 
the sting. But many functions work on string without changing them. 
That's a bit odd, or maybe difficult for new users to understand.
I think, the ideas can be seen as: like other languages have call-by-value 
and call-by-reference (maybe using pointers as in C), REBOL could 
have call-by-value and call-by-word, both working with the same functions, 
as it's all by value, but we just give the word (REBOL's kind of 
reference) as an argument.
Leading to shorter notation and most likely also faster evaluation. 
I can't see any problem yet, but maybe there is!?
Ladislav
13-Oct-2011
[2475]
we are not sure about performance overhead
 - there are greater concerns than just performance here
BrianH
13-Oct-2011
[2476]
Then we would have one more class of arguments that we need to treat 
carefully, rather than trusting the type checking to do it for us. 
This is similar to the none propagation problem.
Geomol
13-Oct-2011
[2477]
Well, REBOL already has double type checking:

>> 4 > 2
== true
>> [4] > [2]
== true
>> [4] > 2
** Script Error: Expected one of: block! - not: integer!
BrianH
13-Oct-2011
[2478x2]
For all those series functions that are non-modifying, except for 
ports, all we have to do to use them safely is to avoid putting ports 
in our data. This isn't usually a problem because it's rare to put 
ports in data; but words, on the other hand, are really common in 
data. This would make a misplaced word in your data not only not 
caught, but also *modified*. That is really bad.
I wasn't joking about the "a valuable debugging aid" comment. That's 
a deal-killer for me.
Henrik
16-Oct-2011
[2480]
What exactly does this mean:

>> a: make bitset! [#"-" - #"+"]
** Script Error: Out of range or past end
** Near: a: make bitset! [#"-" - #"+"]
GrahamC
16-Oct-2011
[2481]
>> make bitset! [ #"+" - #"-" ]
== make bitset! #{
0000000000380000000000000000000000000000000000000000000000000000
}
Sunanda
16-Oct-2011
[2482]
bitset likes its args in ascending order (but Graham beat me to it)
Henrik
16-Oct-2011
[2483]
that seems a bit impractical, but I guess it could complicate the 
function to have both ways.
james_nak
28-Oct-2011
[2484]
Is there a simple way to transform a block of blocks into a single 
block and maintain their types? As follows:
a: [  [1] [2] [3] ]
Changing that to
b: [  1 2 3 ]

You know, outside of looping thru each value and building a new block 
(which I don't mind doing but if there was some simple way)