0 голосов
 
959 просмотров
7.05.2017 / 11:23  Aladdin

Быстрое определение типа Object

работаю над рантаймом языка, т.к. язык динамической типизации возникли проблемы определением типов.
Есть несколько идей:
1. instanceof- вполне удобная штука, но говорят очень медленных. Для рантайма не годится
2. класс обертка. В данный момент использую эту. Есть интерфейс Value с методами getType, asInteger, asFloat, asBoolean и тп., но потребляет много памяти.
т.к. для каждого вычисления создается новый объект типа:
  1. ipush 10 ; new IntegerValue(10)
  2. fpush 3.96 ; new FloatValue(3.96)
  3. add ; new FloatValue(stack.pop().asFloat() + stack.pop().asFloat());
3. Для каждого типа свой стек: iStack, fStack, bStack, zStack, cStack, aStack. и один стек для вычислений workStack
  1. ipush 10 ; iStack.add(10); workStack.add(T_INT);
  2. fpush 3.96 ; fStack.add(3.96); workStack.add(T_FLT);
  3. add
  4.     byte types = workStack.pop() - workStack.pop();  //Int_flt  
  5.      if(types == INT_FLT)
  6.         fStack.add(iStack.pop() + fStack.pop()); workStack.(T_FLT);
и т.п. но это с головной болью.
Есть ли другие способы решения задачи?
Ответы
 
3 голоса
 
# 7.05.2017 / 14:09  Naik
2й вариант + кэширование значений float, integer, etc
7.05.2017 / 15:41  Aladdin
кэширование? не знаю что это.
но при компиляции все литералы типа int, float, long, string заносятся в константный пул.
 
0 голосов
 
# 7.05.2017 / 14:24  Koenig
  1. new FloatValue(stack.pop().asFloat() + stack.pop().asFloat());
???
7.05.2017 / 15:43  Aladdin
заносится в стек результат сложения двух значений
7.05.2017 / 16:54  Koenig
ну *2 не проще? ну или в конструкторе сразу складывать, или там какая то фишка?
 
-1 голос
 
# 7.05.2017 / 14:49  vlavolk
Давай проще

  1. // введем класс значения
  2. final class Value {
  3. // постояные типов
  4. public static final int
  5.     T_UNDEFINED = -1,
  6.     T_INTEGER = 0,
  7.     T_FLOAT = 1,
  8.     T_BOOLEAN = 2;
  9.  
  10. // текущий тип, по умолчанию неизвестный
  11. private int type = Value.T_UNDEFINED;
  12. private int integerValue = 0;
  13. private float floatValue = 0f;
  14. private boolean booleanValue = false;
  15.  
  16. // можно сделать разные конструкторы
  17. public Value(int)
  18. public Value(float)
  19. public Value(boolean)
  20.  
  21. // сеттеры
  22. // если заранее неизвестно
  23. public Object set(Object value) {
  24. // тут уже инстансофом проверим
  25.     if (value instanceof Integer) {
  26.         type = Value.T_INTEGER;
  27.         integerValue = ((Integer)value).intValue();
  28.     } // .. и т.д.
  29. // а вдруг уже Value
  30.     if (value instanceof Value) {
  31.         ...
  32.     }
  33.     return value;
  34. }
  35.  
  36. // для отдельных типов
  37. public int set(int)
  38. public float set(float)
  39. public boolean set(boolean)
  40.  
  41. // вернем тип
  42. public int getType() {
  43.     return type;
  44. }
  45.  
  46. // as
  47. public boolean asInteger()
  48. public boolean asFloat() {
  49.     return type == Value.T_FLOAT;
  50. }
  51. public boolean asBoolean()
  52.  
  53. }

вот тогда тебе нужен будет только 1 стек. Туда ещё можно и другие типы добавить

И насколько мне известно, instaceof работает быстро
7.05.2017 / 14:56  aNNiMON
мало того, что обёртка, так ещё и instanceof внутри.
7.05.2017 / 15:33  vlavolk
так то если неизвестно чо мы ему кормим. И зачем для каждого типа выделять класс? Голова от такого взрывается. Конечно можно навертеть типов но нет. Большая декомпозиция вредит
Всего: 3

Реклама

Мы в соцсетях

tw tg yt gt