Page 1 of 1

Doubt about JavaCard Memory

Posted: Thu Oct 12, 2017 10:27 pm
by afrascoi
I made a simple applet to test the speed of adding arrays, depending whether they are saved in EEPROM or RAM. Since working with variables stored in RAM should be faster, I was really surprised when I noticed no difference between them. I would really like to know where I went wrong, but simply cannot figure it out. Could anyone give me some clues on this question?

Code: Select all

package test;

import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;

public class SimpleMemoryTest extends Applet {
     private static final short ARRAY_SIZE = 32;

     byte[] eeprom_a,  eeprom_b, eeprom_c;
     byte[] ram_a, ram_b, ram_c;
     short[] mem;

     private SimpleMemoryTest() {
          this.mem = new short[2];
     }
     
     public static void install(byte[] bArray, short bOffset, byte bLength) {
          new SimpleMemoryTest().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
     }

     public void process(APDU apdu) {
          if (selectingApplet()) return;

          byte[] buf = apdu.getBuffer();
          switch (buf[ISO7816.OFFSET_INS]) {
          case (byte) 0x00: { // Print memory info to verify where arrays are stored
               mem[0] = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
               mem[1] = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);

               buf[0] = (byte)(mem[0] / 256);
               buf[1] = (byte)(mem[0] % 256);
               buf[2] = (byte)(mem[1] / 256);
               buf[3] = (byte)(mem[1] % 256);
     
               apdu.setOutgoingAndSend((short)0, (short)4);
               break;
          }
          case (byte) 0x01: { // Put arrays in EEPROM.
               this.eeprom_a = new byte[ARRAY_SIZE];
               this.eeprom_b = new byte[ARRAY_SIZE];
               this.eeprom_c = new byte[ARRAY_SIZE];
               break;
          }
          case (byte) 0x02: { // Put arrays in RAM.
               this.ram_a = JCSystem.makeTransientByteArray(ARRAY_SIZE, JCSystem.CLEAR_ON_DESELECT);
               this.ram_b = JCSystem.makeTransientByteArray(ARRAY_SIZE, JCSystem.CLEAR_ON_DESELECT);
               this.ram_c = JCSystem.makeTransientByteArray(ARRAY_SIZE, JCSystem.CLEAR_ON_DESELECT);
               break;
          }
          case (byte) 0x03: { // Add arrays in EEPROM 100 times
               short i, j;

               for (i = (short) 0; i < (short) 100; i++) {
                    for (j = (short) 0; j < (short) ARRAY_SIZE; j++) {
                         eeprom_c[j] = (byte)(eeprom_a[j] + eeprom_b[j]);
                    }
               }
               break;
          }
          case (byte) 0x04: { // Add arrays in RAM 100 times
               short i, j;

               for (i = (short) 0; i < (short) 100; i++) {
                    for (j = (short) 0; j < (short) ARRAY_SIZE; j++) {
                         ram_c[j] = (byte)(ram_a[j] + ram_b[j]);
                    }
               }
               break;
          }
          default:
               ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
          }
     }
}


Re: Doubt about JavaCard Memory

Posted: Fri Oct 13, 2017 3:53 am
by choimillen
When you create a byte array, all values are initialized to 0. Looking at your loops, it seems you're adding 0's only. Smart card operating systems normally do a read before write, to make sure not the same value is written. It saves time, and in case of EEPROM also to prolong the lifetime. I think this is the reason why you see no difference .. because there is no writing. Do something like

Code: Select all

eeprom_c[j] = (byte)(i + j);


Code: Select all

case (byte) 0x03: { // Add arrays in EEPROM 100 times
               short i, j;

               for (i = (short) 0; i < (short) 100; i++) {
                    for (j = (short) 0; j < (short) ARRAY_SIZE; j++) {
                         eeprom_c[j] = (byte)(eeprom_a[j] + eeprom_b[j]);
                    }
               }
               break;
          }
          case (byte) 0x04: { // Add arrays in RAM 100 times
               short i, j;

               for (i = (short) 0; i < (short) 100; i++) {
                    for (j = (short) 0; j < (short) ARRAY_SIZE; j++) {
                         ram_c[j] = (byte)(ram_a[j] + ram_b[j]);
                    }
               }
               break;
}

Re: Doubt about JavaCard Memory

Posted: Fri Oct 13, 2017 4:09 am
by tomwu2016
Are you execute soft simulation in IDE? if so ,there is no diffence.

Re: Doubt about JavaCard Memory

Posted: Fri Oct 13, 2017 5:49 am
by mabel
The size of your test array is rather small, so considering all the overhead of executing other bytecodes, the difference is probably going to be difficult to notice.