paladin-t / my_basic

A lightweight BASIC interpreter written in standard C in dual files. Aims to be embeddable, extendable and portable.
http://paladin-t.github.io/my_basic/
MIT License
507 stars 118 forks source link

Very slow ops on Strings #76

Closed invpe closed 1 year ago

invpe commented 1 year ago

I noticed that FOR on Strings is super slow.


DEF FINDNEWLINEPOS(STRINGUS) 
  FOR ICT = 0 TO LEN(STRINGUS)-1
    CHAR = ASC(MID(STRINGUS,ICT,1))
    IF CHAR = 10 THEN 
      RETURN ICT
    ENDIF
  NEXT ICT 
  RETURN -1
ENDDEF   

PRINT "START";
TEST_STRING = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 
FINDNEWLINEPOS(TEST_STRING)
PRINT "END";

This simple iteration takes :

08:33:58.625 -> START
08:33:59.023 -> END

More than 0.5sec, running ESP32.

Is there a better way of doing this in mybasic ?

invpe commented 1 year ago

A workaround is to register a func that does it fast like below:


/* Get a char a string position */
static int _charat(mb_interpreter_t* s, void** l) {
  int result = MB_FUNC_OK;
  char* arg = 0;
  int_t start = 0;
  char sub[2];
  mb_check(mb_attempt_open_bracket(s, l));
  mb_check(mb_pop_string(s, l, &arg));
  mb_check(mb_pop_int(s, l, &start));
  mb_check(mb_attempt_close_bracket(s, l));

  if ( start < 0 || start >= (int_t)strlen(arg))
  {
    sub[0] = '\0';
  }
  else
  {
    sub[0] = arg[start];
    sub[1] = '\0';
  }
  mb_check(mb_push_string(s, l, mb_memdup(sub, 2)));
  return result;
}

But i might be overcomplicating things, thus asking if withing MB we've got a better solution than mine ;)
invpe commented 1 year ago

Issue on MBStep