OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 28 Апрель, 2024 13:02

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 70 ]  На страницу Пред.  1, 2, 3, 4
Автор Сообщение
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 05 Май, 2006 13:43 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Alexey Veselovsky писал(а):
Иногда функция должна вернуть несколько значений, но это еще можно обойти


std::pair, boost::tuple ;)

Alexey Veselovsky писал(а):
Но основная проблема в том, что например Win32 API сплош и рядом использует возврат значения через параметры (используя указатель),


А Win32 API давно завраплен в нормальные классы ;)

Alexey Veselovsky писал(а):
+ код писаный не мною, а кем-то еще. В результате имеем в одном проекте не хилый зоопарк решений и подходов. Всё в куче. Что несколько раздражает и отвлекает.


Да, есть в С++ такая проблема, особенно для долгоживущих проектов.

Alexey Veselovsky писал(а):
Впринципе проблему бы решило (хотя бы частично) требование явного обозначения параметорв которые подаются на вход, а какие будут на выходе. Обозначение при выхове процедуры. Впрочем, об этом я уже довольно подробно писал.


Согласен, я бы тоже хотел видеть явно в месте вызова возможность изменения аргумента.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 05 Май, 2006 13:45 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Alexey Veselovsky писал(а):
Вопрос - насколько дорога такая поддержка?


Думаю, что настолько, что актуальна только при отладке.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 05 Май, 2006 13:49 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Vlad писал(а):
Trurl писал(а):
А если мы читаем данные или выполняем вычисления и заполняем поля структуры по ходу дела?
И что это меняет? rturn MyStruct(calc(), read());
В другой ветке форума Trurl однажды приводил пример (про return), преобразовав который на данный случай получим следующее:
Код:
Data NewData (int a)
{
  Data d;
  //...
  if (a > 0)
  {
    //...
    d = new Data(1,2,3);
    //...
  }
  //...
  if (a <= 0)
  {
    //...
    d = new Data(3,2,1);
    //...
  }
  //...
  return d;
}
Хотя код правильный, но компилятор этого не понимает и отказывается компилировать: Use of unassigned local variable 'd'.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 05 Май, 2006 14:34 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
Хотя код правильный, но компилятор этого не понимает и отказывается компилировать: Use of unassigned local variable 'd'.


А сразу return кто мешает написать? В любом случае, я бы не стал размазывать инициализацию структуры по телу функции. В особо клиническом случае это можно сделать через дополнительные временные переменные. Все равно это будет лучше, чем структура в "полупроиниченном" виде.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 05 Май, 2006 16:34 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Сергей Губанов писал(а):
Если написать конструктор .... и инициализировать посредством него: g = new Data(1, 2, 3), то всё будет летать...

Хм, обознатушки перепрятушки. Там компилятор сильно оптимизировал вызов new Data(1, 2, 3) из-за того, что аргументы - константы. А вот если аргументы - не константы, а переменные, то ничего и не летает, а по прежнему тормозит.
Код:
MODULE TestPenalty;

  IMPORT Log, Services;
 
  TYPE
    Data* = RECORD
      x*, y*, z*: REAL
    END;

  VAR
    count: INTEGER;

  PROCEDURE Do (x: REAL); (* без инициализации выполняется 10.816 секунд *)
    VAR d: Data;
  BEGIN
    d.x := x; d.y := x + 1.0; d.z := x + 2.0; (* с этой инициализацией 12.408 секунд *)
    INC(count);
    IF x > 0.0 THEN Do(x - 1.0); Do(x - 1.0) END
  END Do;

  PROCEDURE Main*;
    VAR t: LONGINT; a: Data;
  BEGIN
    t := Services.Ticks();
    Do(28.0);
    t := Services.Ticks() - t;
    Log.String("t = "); Log.Int(SHORT(t));
    Log.String(", count = "); Log.Int(count);
    Log.Ln
  END Main;

END TestPenalty.


Код:
namespace ValueTypePenalty
{
  public struct Data
  {
    public double x, y, z;
    public Data (double x, double y, double z)
    {
      this.x = x; this.y = y; this.z = z;
    }
  }

  class Program
  {
    static int count = 0;

    static void Do (double x) // без инициализации выполняется 7.842 секунд
    {
      Data d = new Data(x, x + 1.0, x + 2.0); // с этой инициализацией 23.363 секунд
      count++;
      if (x > 0.0) {Do(x - 1.0); Do(x - 1.0);}
    }

    static void Main (string[] args)
    {
      int t = System.Environment.TickCount;
      Do(28.0);
      t = System.Environment.TickCount - t;
      System.Console.WriteLine("t = " + t + ", count = " + count);
      System.Console.ReadLine();
    }
  }
}

На (многократную) инициализацию структуры Data было затрачено времени:
Код:
12.408 - 10.816 =  1.592 секунд BlackBox Component Pascal
23.363 -  7.842 = 15.521 секунд .Net C#


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пятница, 05 Май, 2006 17:26 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
А вот если аргументы - не константы, а переменные, то ничего и не летает, а по прежнему тормозит.


Ты опять чего-то не то померял. Хотелось бы увидеть сравнение "передача и инициализация" vs "возврат уже инициализированного". И лучше не на рекурсии, а на итерации. А то у меня есть подозрения, что JIT'у с рекурсией сложнее оптимизить.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Суббота, 06 Май, 2006 10:32 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Vlad писал(а):
"передача и инициализация" vs "возврат уже инициализированного"

PROCEDURE Init (OUT d: Data); против d = NewData(); - это что ли?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Суббота, 06 Май, 2006 14:26 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
PROCEDURE Init (OUT d: Data); против d = NewData(); - это что ли?


Да.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Суббота, 06 Май, 2006 15:48 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Vlad писал(а):
Сергей Губанов писал(а):
PROCEDURE Init (OUT d: Data); против d = NewData(); - это что ли?

Да.

Так ясно же, что программа для инициализации структуры вызывающая проседуру Init(d) вместо непосредственной инициализации её полей d.x := ...; d.y := ...; d.z := ...; будет выполняться медленнее. В чём смысл-то такого измерения?
Код:
MODULE TestPenalty;

  IMPORT Log, Services;
 
  TYPE
    Data* = RECORD
      x*, y*, z*: REAL
    END;

  VAR count: INTEGER;
   
  PROCEDURE Init (OUT d: Data; x, y, z: REAL);
  BEGIN d.x := x; d.y := y; d.z := z
  END Init;

  PROCEDURE Do (x: REAL); (* без 'd' выполняется 10.665 секунд *)
    (* VAR d: Data; *)
  BEGIN INC(count);
    (* d.x := x; d.y := x + 1.0; d.z := x + 2.0; *)  (* с такой инициализацией 12.047 секунд *)
    (* Init(d, x, x + 1.0, x + 2.0); *) (* с такой инициализацией 21.691 секунд *)
    IF x > 0.0 THEN Do(x - 1.0); Do(x - 1.0) END
  END Do;

  PROCEDURE Main*;
    VAR t: LONGINT; a: Data;
  BEGIN count := 0;
    t := Services.Ticks();
    Do(28.0);
    t := Services.Ticks() - t;
    Log.String("t = "); Log.Int(SHORT(t)); Log.String(", count = "); Log.Int(count); Log.Ln
  END Main;

END TestPenalty.

Непосредственная инициализация полей структуры: 12.047 - 10.665 = 1.382 секунд.
Инициализация полей структуры с помощью вызова процедуры Init: 21.691 - 10.665 = 11.026 секунд.
Аналогичная инициализация структуры в .Net C# с помощью конструктора (вчерашний результат): 23.363 - 7.842 = 15.521 секунд

Vlad писал(а):
И лучше не на рекурсии, а на итерации. А то у меня есть подозрения, что JIT'у с рекурсией сложнее оптимизить.

А что там меняется-то?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Суббота, 06 Май, 2006 17:12 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
Так ясно же, что программа для инициализации структуры вызывающая проседуру Init(d) вместо непосредственной инициализации её полей d.x := ...; d.y := ...; d.z := ...; будет выполняться медленнее. В чём смысл-то такого измерения?


Не непосредественной, а тоже через вызов функции, создающей и возвращающей новую структуру.

Сергей Губанов писал(а):
Vlad писал(а):
И лучше не на рекурсии, а на итерации. А то у меня есть подозрения, что JIT'у с рекурсией сложнее оптимизить.

А что там меняется-то?


inline сложнее делать.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 70 ]  На страницу Пред.  1, 2, 3, 4

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB