Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - iconmaster

Pages: 1 2 [3] 4 5 6
31
Ooh that is awesome :D . It seems the code gets smaller, right? How well does it get optimized for particularly complex programs?

Thanks!

Well, the Source program is a lot smaller, but that's just because the compiler doesn't inline simple statements yet. The equivalent HPPL program would be a bit smaller if a human did it right now. Eventually, I'll make it replace the TMPs with the statements that the TMPs equal; right now, these temporary variables are created by the Source compiler to allow for statements that can't be inlined in HPPL to be inlined in Source. Also, there isn't optimization yet. But trust me, I have a few ideas.

Also, more progress. Here's a Hello Source program:

Code: [Select]
@export
function hello() {
   print("Hello, Source!")
}

that translates to:

Code: [Select]
#pragma mode( separator(.,;) integer(h32) )

hello();


EXPORT hello()
BEGIN
 LOCAL TMP_1:="Hello, Source!";
 LOCAL TMP_0:=print(TMP_1);
END;



As a bonus, some inner workings- here's the Source Intermediary Language (SIL) output for the Source program that compiles into HPPL:


Code: [Select]
FUNC hello [] []:
MOVS   TMP_1   Hello, Source!
CALL   TMP_0   print   TMP_1
END

32
Thinking about GETPIX again, I was wondering about SETTING data. So here is:

PIXON vs. List Set

Spoiler For Spoiler:
Code: [Select]
TT=MAKELIST(MAKELIST(#0,Y,1,100),X,1,100);
TTT=MAKELIST(MAKELIST(0,Y,1,100),X,1,100);

EXPORT TST()
BEGIN
 PIXON_P(G1,50,50,#0);
END;

EXPORT TST2()
BEGIN
 TT[50,50]:=#0;
END;

EXPORT TST3()
BEGIN
 TTT[50,50]:=0;
END;

ONCOMPILE()
BEGIN
 DIMGROB_P(G1,100,100);
END;

lol_hax=ONCOMPILE;

The results were:

PIXON_PINTSREALS
74 μs4,144 μs3,616 μs

Conclusion: PIXON is impossibly fast. So fast, in fact, that I'm wondering if I messed up my time test somewhere. Of course, even if pixels are really fast, you have to worry about working with ints, which are noticeably slower than reals. If those results are real, though, I might have to suggest working with grobs myself.

33
Guys, I have an announcement. Source is working.

I'm faaaaar from done, but we can now compile this:

Code: [Select]
field x as real = 3

function test() {
   x = 1 + 1
}

into this:

Code: [Select]

#pragma mode( separator(.,;) integer(h32) )


test();
x:=3;




test()
BEGIN
 LOCAL TMP_1:=1;
 LOCAL TMP_2:=1;
 LOCAL TMP_0:=TMP_1+TMP_2;
 x:=TMP_0;
END;

This is a huge step for the Source compiler. Right now, there is a huge lack of minification, as you can see. This will be fixed once the full syntax of Source gets added to the compiler.

34
Crap!

That might be quite problematic since the code gets compiled when you send it across... I'll have to check that.

Also, I think storing a char directly also does not require any memory allocations since the size isn't changing.

Hmm? You can STORE characters using that notation too? Didn't know that.

It's a good thing you hang around here, Tim. We'd never have any documentation otherwise!


EDIT: Speaking of documentation, I was looking at #pragma. Can it accept any other arguments tham mode? In mode, can it only take separator and integer modes?

35
Okay, here's more speed tests! I'll put the more relevant ones in the OP.


GETPIX vs. Lists

Maybe getting ints from a grob is faster than ints from a list. Or maybe even reals from a list!

Test 1 is GETPIX. Test 2 is getting a value from a 2d list of #ints. Test 3 is getting from a list of reals.

Spoiler For Spoiler:
Code: [Select]
TT=MAKELIST(MAKELIST(#0,Y,1,100),X,1,100);
TTT=MAKELIST(MAKELIST(0,Y,1,100),X,1,100);


EXPORT TST()
BEGIN
 GETPIX_P(G1,10,10);
END;


EXPORT TST2()
BEGIN
 TT[10,10];
END;


EXPORT TST3()
BEGIN
 TTT[10,10];
END;


ONCOMPILE()
BEGIN
 DIMGROB_P(G1,100,100);
END;


lol_hax=ONCOMPILE();

Here are the results:

GETPIXINTS[x,y]REALS[x,y]
91.2 μs82.8 μs50.0 μs

Conclusion: GETPIX is slower than list access, at least for smallish indices. However, the main problem is probably the fact that you're getting back an integer, which is slow.

Big 1D Data

Let's compare strings to lists again. Let's bring this to THE MAX.

Spoiler For Spoiler:
Code: [Select]
TT=MAKELIST(49,X,1,10000);
TTT=ΣLIST(MAKELIST("1",X,1,10000));

EXPORT TST()
BEGIN
 TT[9999];
END;

EXPORT TST2()
BEGIN
 TTT[9999];
END;

The results are:

LIST[9999]STRING[9999]
81.8 μs88.4 μs

Conclusion: Lists still rule, but the divide IS closing ever so slightly.


2D data: Let's get big


The biggest power of 10 I can get for a list dimension is 100x100. Hmm.


Spoiler For Spoiler:
Code: [Select]
TT=MAKELIST(MAKELIST(Y,Y,1,100),X,1,100);
MM=MAKEMAT(I+J,100,100);


EXPORT TST()
BEGIN
 TT[99,99]
END;


EXPORT TST2()
BEGIN
 MM[99,99]
END;


EXPORT TST3()
BEGIN


END;

The results were:

LIST[99,99]MAT[99,99]
82.2 μs97 μs

Conclusion: Lists are still better. I'd test them out for more beefy values, but I can't. I run out of memory first!

Setting lists and strings

Well, I was just informed that you can put values IN strings. So let's test that out!

Spoiler For Spoiler:
Code: [Select]
TT=MAKELIST(49,X,1,1000);
EXPORT TTT=ΣLIST(MAKELIST("1",X,1,1000));

EXPORT TST()
BEGIN
 TT[999]:=5326;
END;

EXPORT TST2()
BEGIN
 TTT[999]:=5326;
END;

The results were:

LIST[999]STRING[999]
613.0 μs112.6 μs

Conclusion: Setting values is much, much slower than getting them. Here, strings serve as an EXTREMELY good storage mechanism. So strings are better if you're willing to have a longer access time.


Making large strings

How does one make a large string programmatically? Well, there's the built in ΣLIST function that works, but what else can work? CHAR could do.

The strings are 100 characters long.

Spoiler For Spoiler:
Code: [Select]
EXPORT TST()
BEGIN
 ΣLIST(MAKELIST("1",X,1,100));
END;

EXPORT TST2()
BEGIN
 CHAR(MAKELIST(49,X,1,100));
END;

The results are:

ΣLISTCHAR
2,153 μs561 μs

Conclusion: CHAR is by far better here. It's a good thing CHAR works on lists!


Even More Iteration Code


ITERATE is a function that exists. It's hard to make it work like MAKELIST, but sometimes you don't need it to work like MAKELIST ;) .


Spoiler For Spoiler:
Code: [Select]
FF()
BEGIN

END;

EXPORT TST()
BEGIN
 MAKELIST(FF(),X,1,1000);
END;

EXPORT TST2()
BEGIN
 ITERATE(FF(),X,1,1000);
END;

EXPORT TST3()
BEGIN
 FOR I FROM 1 TO 1000 DO
  FF();
 END;
END;

The results are as follows:

MAKELISTITERATEFOR
10,500 μs7,900 μs18,900 μs

Conclusion: If you don't care too much about the iteration count, ITERATE is better. I would bet it to be superior even if you put code in FF to make ITERATE give you back a real iteration value.


... Do I bet?

I'm feeling lucky.

Spoiler For Spoiler:
Code: [Select]
FF(X)
BEGIN
 RETURN X+1;
END;

EXPORT TST()
BEGIN
 MAKELIST(FF(X),X,1,1000);
END;

EXPORT TST2()
BEGIN
 ITERATE(FF(X),X,1,1000);
END;

EXPORT TST3()
BEGIN
 FOR I FROM 1 TO 1000 DO
  FF(I);
 END;
END;

The results are:

MAKELISTITERATEFOR
35,700 μs39,300 μs48,200 μs

Conclusion: Passing a parameter costs you a lot of time.

Oh, and I guess I lost that bet.

36
Another interesting dynamic of HPPL is how global variables work. The following program show you a message when the program is compiled:

Code: [Select]
FF()
BEGIN
 MSGBOX("OH MY");
END;

GLOBALVAR=FF();

I have a few ideas about how this might come in handy. ;)

37
(If this test was done with a ClassPad II, I would be 65 years old and retired by the time it's finished. :trollface:)


Thanks a lot for this post by the way. THis might be pretty handy because sometimes we might need the fastest possible speed, but not be aware of what is actually faster. It sucks to have to rewrite most of the code after discovering we could have done it faster in certain ways >.<

Yeah, I know what you mean. Looking back at HP Tetris, I realize that representing the grid with a complex matrix was a bad idea. :P

Also, speed was a major concern for me regarding tilemapping because I was not sure if I should use lists, matrices, strings or images. I am not surprised that strings are slower, though, because on the TI models they were much slower than lists (in fact, the farther a character was in a string, the slower it was to read it, so inside a 2000 bytes large string, reading map data at the beginning was about 3 times faster than at the end). For data storage and reading, could you test how fast/slow it is with Pixel-test commands? Using such data would make it much easier to design tilemap data, but if the speed loss is considerable, then it might not be worth it.

Do you mean testing list access vs. pixel access? If that's what you mean, sure! Im going to guess that lists are faster, but who knows! This is why I'm testing.

38
HP Calculators / HP Prime Relative Speed Testing- What is REALLY faster?
« on: October 08, 2014, 05:30:45 pm »
As you guys may know, I'm working on an application that (in a way) optimizes HPPL code. So recently, I've been time-testing several methods of computation. So if you want to know absolutely what's faster to execute, you now have this thread!


I take 10,000 to 40,000 executions of a code snippet, and average the returned execution times. All parts of the programs being tested against each other have all other variables/code held constant. This isn't EXACTLY how long each operation takes; since there's boilerplate in there, too, all the times are relative. I did all of these on a physical calculator.

All units are in microseconds.


Now, on to the times!


PIECEWISE vs. IF...THEN...ELSE vs. IFTE

This was a test that looked like this:

Spoiler For Spoiler:
Code: [Select]
TEST1()
BEGIN
 X:=RANDINT(1,3);
 RETURN PIECEWISE(X==1,3,X==2,2,1);
END;

TEST2()
BEGIN
 X:=RANDINT(1,3);
 IF X==1 THEN
  RETURN 3;
 ELSE
  IF X==2 THEN
   RETURN 2;
  ELSE
   RETURN 1;
  END;
 END;
END;

TEST3()
BEGIN
 X:=RANDINT(1,3);
 RETURN IFTE(X==1,3,IFTE(X==2,2,3));
END;

So it tested an IF and a sub-IF.

The results are:

PIECEWISEIF...THEN...ELSEIFTE
115.3 μs117.4 μs115.2 μs

Conclusion: IFTE is very slightly faster here, but PIECEWISE might actually be better for larger chains of ELSEs. IF...END is right out.


PIECEWISE vs. IF...THEN...ELSE vs. IFTE... REDUX!

Let's test this thing against a version with no sub-case.

Spoiler For Spoiler:
Code: [Select]
TEST1()
BEGIN
 X:=RANDINT(1,2);
 RETURN PIECEWISE(X==1,3,4);
END;

TEST2()
BEGIN
 X:=RANDINT(1,2);
 IF X==1 THEN
  RETURN 3;
 ELSE
  RETURN 4;
 END;
END;

TEST3()
BEGIN
 X:=RANDINT(1,2);
 RETURN IFTE(X==1,3,4);
END;

The results are:

PIECEWISEIF...THEN...ELSEIFTE
100.6 μs99.5 μs98.5 μs

Conclusion: IFTE is the clear winner for simple IF cases.


MAKELIST vs. FOR

Let's execute a function. 1,000 times.

Spoiler For Spoiler:
Code: [Select]
FF(X)
BEGIN
 RETURN X;
END;

TEST1()
BEGIN
 MAKELIST(FF(I),I,1,1000);
END;

TEST2()
BEGIN
 FOR I FROM 1 TO 1000 DO
  FF(I);
 END;
END;

The results of this test are:

MAKELISTFOR
12,900 μs15,200 μs

Conclusion: MAKELIST is faster. Use it instead of for loops even if you throw away what it returns.


MAKELIST vs. FOR, Part 2

Let's make them go backwards.

Spoiler For Spoiler:
Code: [Select]
FF(X)
BEGIN
 RETURN X;
END;

TEST1()
BEGIN
 MAKELIST(FF(I),I,1000,1,-1);
END;

TEST2()
BEGIN
 FOR I FROM 1000 DOWNTO 1 DO
  FF(I);
 END;
END;

The results of this test are:

MAKELISTFOR
14,200 μs15,200 μs

Conclusion: MAKELIST takes a hit here, but is still better than FOR.


MAKELIST vs. FOR, Part 3

we had -1 as a step, so let's try 2.

Spoiler For Spoiler:
Code: [Select]
FF(X)
BEGIN
 RETURN X;
END;

TEST1()
BEGIN
 MAKELIST(FF(I),I,1,2000,2);
END;

TEST2()
BEGIN
 FOR I FROM 1 TO 2000 STEP 2 DO
  FF(I);
 END;
END;

The results of this test are:

MAKELISTFOR
13,700 μs15,200 μs

Conclusion: MAKELIST still wins. Also, the fact that FOR kept getting the same time each run is really creepy.


To get an int: From a string, list, or matrix?

What is the best way to store ints? Let's find out:

Spoiler For Spoiler:
Code: [Select]
SS:="1234567890";
TT:={48,49,50,51,52,53,54,55,56,57,58};
MM:=[[48,49,50,51,52,53,54,55,56,57,58]];

TEST1()
BEGIN
 RETURN SS[3];
END;

TEST2()
BEGIN
 RETURN TT[3];
END;

TEST3()
BEGIN
 RETURN MM[1,3];
END;

The results were:

STRINGLISTMATRIX
54.0 μs47.1 μs63.0 μs

Conclusion: Strings, quite surprisingly, suck. Not so surprisingly, matrices are bad at storing 1D data.


Real 2D data - Lists of Matrices?

Well, what is a matrix good at? 2D data, right? Well, let's see:

Spoiler For Spoiler:
Code: [Select]
TT:={{1,2,3},{4,5,6}};
MM:=[[1,2,3],[4,5,6]];
TEST1()
BEGIN
 RETURN TT[1,2];
END;

TEST2()
BEGIN
 RETURN MM[1,2];
END;

The results were:

LISTMATRIX
48.7 μs53.3 μs

Conclusion: If you want speed, lists seem like the way to go.


3D data: Lists vs. complex arrays

Well, matrices can technically store 2 reals per slot: Complex arrays exist. So let's see if that's a good idea.

Spoiler For Spoiler:
Code: [Select]
TT:={{{1,1},{2,2}},{{3,3},{4,4}}};
MM:=[[(1,1),(2,2)],[(3,3),(4,4)]];
TEST1()
BEGIN
 RETURN TT[1,2,1];
END;

TEST2()
BEGIN
 RETURN IM(MM[1,2]);
END;

The results were:

LISTMATRIX
50.3 μs60.0 μs

Conclusion: Matrices are useless.

Well, unless you're doing math with them, I GUESS.


GETPIX vs. Lists

Maybe getting ints from a grob is faster than ints from a list. Or maybe even reals from a list!

Test 1 is GETPIX. Test 2 is getting a value from a 2d list of #ints. Test 3 is getting from a list of reals.

Spoiler For Spoiler:
Code: [Select]
TT=MAKELIST(MAKELIST(#0,Y,1,100),X,1,100);
TTT=MAKELIST(MAKELIST(0,Y,1,100),X,1,100);

EXPORT TST()
BEGIN
 GETPIX_P(G1,10,10);
END;

EXPORT TST2()
BEGIN
 TT[10,10];
END;

EXPORT TST3()
BEGIN
 TTT[10,10];
END;

ONCOMPILE()
BEGIN
 DIMGROB_P(G1,100,100);
END;

lol_hax=ONCOMPILE();

Here are the results:

GETPIXINTS[x,y]REALS[x,y]
91.2 μs82.8 μs50.0 μs

Conclusion: GETPIX is slower than list access, at least for smallish indices. However, the main problem is probably the fact that you're getting back an integer, which is slow.


Big 1D Data

Let's compare strings to lists again. Let's bring this to THE MAX.

Spoiler For Spoiler:
Code: [Select]
TT=MAKELIST(49,X,1,10000);
TTT=ΣLIST(MAKELIST("1",X,1,10000));

EXPORT TST()
BEGIN
 TT[9999];
END;

EXPORT TST2()
BEGIN
 TTT[9999];
END;

The results are:

LIST[9999]STRING[9999]
81.8 μs88.4 μs

Conclusion: Lists still rule, but the divide IS closing ever so slightly.


2D data: Let's get big

The biggest power of 10 I can get for a list dimension is 100x100. Hmm.

Spoiler For Spoiler:
Code: [Select]
TT=MAKELIST(MAKELIST(Y,Y,1,100),X,1,100);
MM=MAKEMAT(I+J,100,100);

EXPORT TST()
BEGIN
 TT[99,99]
END;

EXPORT TST2()
BEGIN
 MM[99,99]
END;

EXPORT TST3()
BEGIN

END;

The results were:

LIST[99,99]MAT[99,99]
82.2 μs97 μs

Conclusion: Lists are still better. I'd test them out for more beefy values, but I can't. I run out of memory first!


Setting lists and strings

Well, I was just informed that you can put values IN strings. So let's test that out!

Spoiler For Spoiler:
Code: [Select]
TT=MAKELIST(49,X,1,1000);
EXPORT TTT=ΣLIST(MAKELIST("1",X,1,1000));

EXPORT TST()
BEGIN
 TT[999]:=5326;
END;

EXPORT TST2()
BEGIN
 TTT[999]:=5326;
END;

The results were:

LIST[999]STRING[999]
613.0 μs112.6 μs

Conclusion: Setting values is much, much slower than getting them. Here, strings serve as an EXTREMELY good storage mechanism. So strings are better if you're willing to have a longer access time.


Making large strings

How does one make a large string programmatically? Well, there's the built in ΣLIST function that works, but what else can work? CHAR could do.

The strings are 100 characters long.

Spoiler For Spoiler:
Code: [Select]
EXPORT TST()
BEGIN
 ΣLIST(MAKELIST("1",X,1,100));
END;

EXPORT TST2()
BEGIN
 CHAR(MAKELIST(49,X,1,100));
END;

The results are:

ΣLISTCHAR
2,153 μs561 μs

Conclusion: CHAR is by far better here. It's a good thing CHAR works on lists!


Even More Iteration Code

ITERATE is a function that exists. It's hard to make it work like MAKELIST, but sometimes you don't need it to work like MAKELIST ;) .

Spoiler For Spoiler:
Code: [Select]
FF()
BEGIN

END;

EXPORT TST()
BEGIN
 MAKELIST(FF(),X,1,1000);
END;

EXPORT TST2()
BEGIN
 ITERATE(FF(),X,1,1000);
END;

EXPORT TST3()
BEGIN
 FOR I FROM 1 TO 1000 DO
  FF();
 END;
END;

The results are as follows:

MAKELISTITERATEFOR
10,500 μs7,900 μs18,900 μs

Conclusion: If you don't care too much about the iteration count, ITERATE is better. I would bet it to be superior even if you put code in FF to make ITERATE give you back a real iteration value.


... Do I bet?

I'm feeling lucky.

Spoiler For Spoiler:
Code: [Select]
FF(X)
BEGIN
 RETURN X+1;
END;

EXPORT TST()
BEGIN
 MAKELIST(FF(X),X,1,1000);
END;

EXPORT TST2()
BEGIN
 ITERATE(FF(X),X,1,1000);
END;

EXPORT TST3()
BEGIN
 FOR I FROM 1 TO 1000 DO
  FF(I);
 END;
END;

The results are:

MAKELISTITERATEFOR
35,700 μs39,300 μs48,200 μs

Conclusion: Passing a parameter costs you a lot of time.

Oh, and I guess I lost that bet.



Fun fact with lists: Use LIST[0] to get the last element of a list. Set something to LIST[0] to append it to the end of the list. This is a sensible way to do things. Yessir.




Well, that's really all the useful ones I have right now. I'll do more later. Feel free to ask me for more comparisons!

39
I found this in an old changelog:


Quote
"1234"[n] now works to access a specific character in a string with no memory copy.


Note to self: Accessing from strings are now probably faster than accessing from a list.


EDIT: Did some speed testing. No, it's not faster.

40
Indeed. I am really curious about how this language will look like. Just make sure it's not overly cryptic like Antidisassemblage on the 84+. Ironically, that language was meant to bridge the gap between TI-BASIC and Z80 ASM, yet it required learning ASM in order to even understand why Squirrelbox works in certain ways, which defeated the entire point.

Well, guess what? I quickly wrote up some syntax. It's at https://github.com/iconmaster5326/Source/blob/master/SyntaxGuide.src ! Try downloading the NetBeans plugin to read it in full color.

No, I'm not done with said syntax sheet yet. It's very bare-bones ATM.

The only invented languages I know of that were successful are Axe and Nspire C++. I hope this will add another one to the list. :)

Well, thank you. I'll do my best.


EDIT: Well, it seems pointers are on the table.


Code: [Select]
FUNC(a)
BEGIN
 MSGBOX("call "+a);
END;


FUNC2()
BEGIN
 LOCAL AA=1;
 LOCAL BB='FUNC(AA)';
 EVAL(BB);
 AA:=2;
 EVAL(BB);
 AA:=3;
 RETURN BB;
END;


EXPORT TST2()
BEGIN
 LOCAL XX=FUNC2();
 LOCAL AA=4;
 EVAL(XX);
END;


41
Hi and nice to see you again. :D

Hey! I just updated the OP, funny thing.

As for the new name, just keep in mind it might confuse people if they post actual source code literally :P , but I like the idea. Btw do you plan to write a tutorial on how to code in Source when finished? It might be good to post about it here if that's the case, so more people see it.

Source is a good name. I don't see how it could be confusing. :P


Anyways, I plan on writing Source tutorials soonish. Probably before the whole project is done, actually! Sooner than later, though, will be coming a description of the syntax. Syntax is important! How else can I get feedback on this thing?

btw is this still a language written in HP PPL or does it now use ASM/C through any HP Prime exploit?

Sadly, I have not found any good haxx. :P It will be initially entirely compiled to HPPL. However, as we learn more about the OS, I am willing to add in features in ASM/C.


42
So you guys may be surprised to learn that this project isn't dead. Actually, I've restarted from scratch.

Today, I'm introducing Source.

Source is the new name for HPP+. I made the change because I might (might!) make this language compilable to other places eventually.

There is currently the Source compiler, which parses Source programs but doesn't compile it yet, and a Source plugin for the IDE Netbeans. The plugin has syntax highlighting and error displaying already built in.


Take a look at https://github.com/iconmaster5326/Source .

Soon, I plan on giving you guys a WIP document on the exact syntax of Source. Also, I really need to update the OP.

One las thing, concerning pointers: I've worked with QUOTE a little (I need to show you guys how it works), but it acts quite... Uniquely. I may or may not be able to figure out how to use this to make pointers fast.

43
HP Calculators / Re: Let's hack the HP Prime!
« on: October 06, 2014, 03:52:15 pm »
I loaded the .BIN file from the old SDK OS into a ARM dissassembler (armU, to be exact), and I found that I can emulate it's basic operations from there. I discovered what memory addresses correspond to the splash screen bootup and the main input loop.

I'll post more specifics later.

44
I have another bug! This one's rather crazy.


My calculator has somehow equated the number two with the empty string.


If I type in 2 to the command line, I get back "". Same goes for typing in 1+1. {1,2,3}? No, it's {1,"",3}. 2 is "" even in programs.


2 works fine in the CAS, though.

45
HP Calculators / Re: Let's hack the HP Prime!
« on: June 27, 2014, 08:15:00 am »
A reminder to people who want to write patches for this thing: We already have half of the HP Prime's source code. It's called xcas. :P

Pages: 1 2 [3] 4 5 6