2009-11-10 4 views
1

UPDATE Основные вопросы остаются те под пример, но я предполагаю, что это сводится к :Изменение внутреннего представления во время выполнения

** Если у вас есть тип, где 99% значений может быть представленным в одном быстрым, мощным типом и только 1% в очень тяжелого типа (скажем, int vs. BigInteger) Как его представить? **

Школа, в которой мы много узнали о внутренних представлениях, но никогда, как изменить ее во время выполнения. Я имею в виду: предположим, что у вас есть класс, представляющий десятичную дробь, но вы используете целое число, чтобы представлять его внутренним, до тех пор, пока вам не понадобится большее значение, чем целое число, и только, чем изменение представления ...

Я никогда не думал об этом раньше, и когда я думал об этом, я думал, что это никогда не сработает, поскольку все проверки убьют его. Но я только что сделала тест, так как я слишком любопытен для своего собственного блага, и там существуют ситуации, когда изменение представления более perormant: учитывая этот интерфейс:

interface INumber 
    { 
     void add1000(); 
     void SetValue(decimal d); 
     decimal GetValue();      
    } 

Я нашел последний из двух реализаций, чтобы быть более мощным во многих ситуациях, в том числе this one, что я сочинял, чтобы привлечь как можно больше идей, которые я мог бы по этому вопросу (не репутация, это сообщество)

1. Representation by only a decimal 

     public class Number1:INumber 
     { 

      private decimal d { get; set; } 


      public void add1000() 
      { 
       d += 1000; 
      } 



      public decimal GetValue() 
      { 
       return d; 
      } 



      public void SetValue(decimal d) 
      { 
       this.d = d; 
      } 

     } 


2. Representation by a decimal and an int 

public class Number2:INumber 
    { 
     private bool usedecimal; 
     private int i; 
     private decimal d; 

     public void add1000() 
     { 
      if (usedecimal) 
      { 
       d += 1000; 
       return; 
      } 

      i += 1000; 

      if (i > 2147480000) 
      { 
       d = i;    
       usedecimal = true;    
      } 


     } 

     public void SetValue(decimal d) 
     { 
      try 
      { 
       i = (int)d; 

      } 
      catch (OverflowException e) 
      { 

       this.d = d; 
      } 

     } 

     public decimal GetValue() 
     { 
      return Math.Max(i,d); 
     } 
    } 
} 

Мой вопрос заключается в следующем:

Это кажется н , Я отсутствовал, но это должно быть кровотечение очевидным. Может ли кто-нибудь помочь мне с этим?

  • Существуют ли руководящие принципы для смешанных представлений, когда их использовать, когда нет?
  • Как угадать, когда смешанная реклама может быть быстрее без бенчмаркинга?
  • Любые примеры?
  • Любые узоры?
  • Любые идеи по этому вопросу?
+2

И ваш вопрос ...? – Kevin

+0

@ kevin, извините не было – Peter

ответ

8

Если у вас есть тип, в котором 99% значений могут быть представлены одним быстрым, мощным типом и только 1% в очень тяжелом типе (например, int vs. BigInteger) Как его представить?

Реализации BigInteger обычно выполняют именно это; они хранят все в ints или longs, пока что-то не переполнится, и только после этого они идут на более тяжелую реализацию.

Существует множество способов его представления. Узор мне нравится:

public abstract class Thing 
{ 
    private class LightThing : Thing 
    { ... } 
    private class HeavyThing : Thing 
    { ... } 
    public static Thing MakeThing(whatever) 
    { /* make a heavy or light thing, depending */ } 
    ... etc ... 
} 

Существуют рекомендации для смешанных представлений, когда использовать их, когда нет?

Несомненно.Мы можем легко составить такой список. Этот метод имеет смысл, если:

(1) легкая реализация намного легче, чем в супертяжелом реализации

(2) типичное использование попадает в легком пути кода большую часть времени

(3) стоимость обнаружения перехода не является значительной стоимостью по сравнению со стоимостью решения в тяжелом весе.

(4) более сложное решение с двумя представлениями необходимо для достижения ориентированной на клиента, реалистичной цели производительности.

Как иметь догадки, когда смешанная перестройка может быть быстрее без бенчмаркинга?

Нельзя. Принятие решений о производительности на основе догадок является аргументом перед фактами. Приводные решения по эффективности на realistic, сфокусированный на клиента, data-driven анализ, а не на догадках. Если на протяжении многих лет я узнал об анализе производительности, то, что мои судороги, как правило, ошибочны.

Любые примеры?

Любое количество вариантов реализации BigInteger.

Любые узоры?

Избивает меня. Я не из тех, кто запоминает таксономию шаблонов.

Любые идеи по этому вопросу?

См. Выше.

+0

Это отличный пример того, как реализовать такую ​​систему; шаблон фабрики (используемый с, я предполагаю, неизменяемый класс) является лучшим шаблоном для последующего, чем «изменение внутреннего представления во время выполнения». Это может показаться смысловой разницей, поскольку она делает то же самое * в действии *, но это, по-видимому, намного более чистый способ делать вещи. –

Смежные вопросы