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.


Topics - iconmaster

Pages: [1]
1
HP Calculators / A Quine in HP Prime
« on: December 03, 2014, 05:33:40 pm »
Just a little something for the lulz. Name the file it goes in "QUINE", of course.

Code: [Select]
EXPORT QUINE()
BEGIN
 MSGBOX(Programs["QUINE"])
END;

While I'm at it, have a program (named SELFMOD) that stores a variable, but never uses the := operator to store new values in it:

Code: [Select]
x:=0;

EXPORT SELFMOD()
BEGIN
 MSGBOX("x is "+x);
 Programs["SELFMOD"]:=LEFT(Programs["SELFMOD"],3)+(x+1)+MID(Programs["SELFMOD"],INSTRING(Programs["SELFMOD"],";"));
END;

2
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!

3
Once upon a time, I was writing programs for the HP Prime in HPPL. The more I worked in HPPL, the more I became dissatisfied with the language. I mean, it was usable, but I wanted better.

So I decided to make something better. I started work on Source. It's a programming language.

Source is a procedural, statically-typed bytecode-compiled language that can either compile to whatever platform you need or interpret directly on your computer. Currently, it compiles to HPPL.

Source gives you control. It's statically typed, so you can read your code more easily. It can assume types, so it's not needlessly verbose. You can control how it compiles through directives.

Source is flexible. It provides data structures and user types. You can define methods for data types anywhere. You can organise your code into packages. Source even can handle cyclic dependencies!

Source has tools. Compile it into HPPL from the command line, or use SourceBench to write and compile code on the fly. Use SourceBox to run your code on your PC. Run SourceLine to interactively execute Source code.

Source isn't done yet. The core libraries still need implemented, not to mention a bunch of features such as custom structs and classes. In the future, it will be able to compile to a bunch of places, not just HPPL. I wouldn't describe it as 'usable' yet. But stay tuned!

Anyways, the important bit: The link. Check out the source code at:

https://github.com/iconmaster5326/Source

Want to download Source? Want to learn more? Check out the wiki at:

https://github.com/iconmaster5326/Source/wiki

The wiki has downloads, documentation, and tutorials.

4
HP Calculators / TETRIS for the HP Prime!
« on: April 04, 2014, 03:59:57 pm »
HP TETRIS!

I've recently updated my HP firmware, and suddenly I can program games in it! My first project is Tetris.

Screenshots:



Features:

  • Classic Tetris gameplay
  • Acurite piece rotation
  • Both soft-drop and hard-drop keys
  • Adjustable difficulty level
  • Original Tetris scoring rules
  • High-score tables - challenge your friends!

Download:

Get this program here!

Future Plans:

  • Placement guides
  • Showing the next piece
  • Better graphics

Pages: [1]