Еще пара вопросов
От: Niovol  
Дата: 05.02.08 09:11
Оценка:
1.Допустим, есть абстрактный класс A, в котором содержится список элементов этого же класса, например, protected con : list[A]. Можно ли указать в классе-наследнике B : A, чтобы этот список con мог содержать только элементы другого класса C : A или производные от него X : C?

2.Когда я программировал на с++, я создавал специальный класс Globals со статическими членами для глобальных переменных и методов. Тут что-то не получается обратиться к статической переменной. Как быть?
Re: Еще пара вопросов
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.02.08 18:23
Оценка:
Здравствуйте, Niovol, Вы писали:

N>1.Допустим, есть абстрактный класс A, в котором содержится список элементов этого же класса, например, protected con : list[A]. Можно ли указать в классе-наследнике B : A, чтобы этот список con мог содержать только элементы другого класса C : A или производные от него X : C?


Можно в наследнике создать свойство с тем же именем, но другим типом:
using System.Console;
using SCG = System.Collections.Generic;

public class A
{
  public Collection : SCG.IList[A] { get { array[A(), A()] } }
}

public class B : A
{
  public new Collection : SCG.IList[B] { get { array[B(), B()] } }
}

module Program
{
  Main() : void
  {
    def b = B();
    def a = A();
    WriteLine(a.Collection[1].GetType().Name);
    WriteLine(b.Collection[1].GetType().Name);
    _ = ReadLine();
  }
}



N>2.Когда я программировал на с++, я создавал специальный класс Globals со статическими членами для глобальных переменных и методов. Тут что-то не получается обратиться к статической переменной. Как быть?


Должно получаться. Можно просто обявить модуль (в нем все члены статические):
module X
{
  public Y : int = 1;
}
...
WriteLine(X.Y)
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Еще пара вопросов
От: Niovol  
Дата: 09.02.08 07:12
Оценка:
Вот такая еще проблема. Есть классы A, B и C. B — наследник класса А. В классе С есть функция, которая принимает по ссылке элемент класса А. Нужно извне вызвать функцию от ссылки на элемент класса B. При вызове — ошибка. Вопрос касается в принципе не только немерле, но и c#.
Re[2]: Еще пара вопросов
От: Сергей Туленцев Россия http://software.tulentsev.com
Дата: 09.02.08 12:11
Оценка: +1
Здравствуйте, Niovol, Вы писали:

N>Вот такая еще проблема. Есть классы A, B и C. B — наследник класса А. В классе С есть функция, которая принимает по ссылке элемент класса А. Нужно извне вызвать функцию от ссылки на элемент класса B. При вызове — ошибка. Вопрос касается в принципе не только немерле, но и c#.


Эээ, ошибочный код приведи, плиз. Так ничего не понятно
... << RSDN@Home 1.2.0 alpha rev. 789>>
--
Re[3]: Еще пара вопросов
От: Niovol  
Дата: 10.02.08 18:01
Оценка:
Здравствуйте, Сергей Туленцев, Вы писали:

СТ>Эээ, ошибочный код приведи, плиз. Так ничего не понятно



public abstract class Element
{
//...
}



public class Perceptron : Element, IBackPropagationInstructable
{
//...
}



  public class Instructor
  {
    //...
    public Instruct(Net : ref Element) : void
    {
      match(Net)
      {
        | _ is IBackPropagationInstructable =>
          {
            // Тут операции с переменной Net
          }
        | _ => {}
      }
    }
  }



Далее код на с#, который использует dll библиотеку классов, написанных на немерле.

  Perceptron p = new Perceptron();
  Instructor Ins = new Instructor();
  //...
  Ins.Instruct(ref p);


Error 1 The best overloaded method match for 'NeuroV.Instructor.Instruct(ref NeuroV.Construction.Element)' has some invalid arguments
Error 2 Argument '1': cannot convert from 'ref NeuroV.Models.Perceptron' to 'ref NeuroV.Construction.Element'
Re: Еще пара вопросов
От: Niovol  
Дата: 10.02.08 18:14
Оценка:
Как я понял, немерле основан на функциональном подходе, а всякие циклы описаны макросами через вызовы функций. Если же, к примеру, пускать обычный for(mutable i...), не получится ли время исполнения больше, чем следует ожидать?

У меня, кажется, на немерле программы работают по крайней мере в 2 раза дольше, чем на с++. Не знаю, дело в кривом написании кода, или на .NET жаловаться. Я как бы с .NET недавно столкнулся, до этого на чистом с++ программировал.
Re[4]: Еще пара вопросов
От: Сергей Туленцев Россия http://software.tulentsev.com
Дата: 10.02.08 21:01
Оценка: +1
Здравствуйте, Niovol, Вы писали:

N>Здравствуйте, Сергей Туленцев, Вы писали:


N>Error 1 The best overloaded method match for 'NeuroV.Instructor.Instruct(ref NeuroV.Construction.Element)' has some invalid arguments

N>Error 2 Argument '1': cannot convert from 'ref NeuroV.Models.Perceptron' to 'ref NeuroV.Construction.Element'

ECMA-334, Overload resolution

14.4.2.1 Applicable function member
A function member is said to be an applicable function member with respect to an argument list A when all
of the following are true:
• The number of arguments in A is identical to the number of parameters in the function member
declaration.
• For each argument in A, the parameter passing mode of the argument (i.e., value, ref, or out) is
identical to the parameter passing mode of the corresponding parameter, and
o for a value parameter or a parameter array, an implicit conversion (§13.1) exists from the type of the
argument to the type of the corresponding parameter, or
o for a ref or out parameter, the type of the argument is identical to the type of the corresponding
parameter. [Note: After all, a ref or out parameter is an alias for the argument passed. end note]
--
Re[5]: Еще пара вопросов
От: Niovol  
Дата: 10.02.08 21:24
Оценка:
Ок, т.е. по определению типы должны совпадать? А если все-таки нужно передать, передавать просто не по ссылке? Тогда будет производиться копирование экземпляра? Мне же нужно производить манипуляции с любым из переданных наследников конкретного класса.

Помнится, в с++ подобное я передавал указателями. Но в дот нете ведь нет указателей? Как быть в таком случае?
Re[6]: Еще пара вопросов
От: Сергей Туленцев Россия http://software.tulentsev.com
Дата: 10.02.08 21:27
Оценка: +1
Здравствуйте, Niovol, Вы писали:

N>Ок, т.е. по определению типы должны совпадать? А если все-таки нужно передать, передавать просто не по ссылке? Тогда будет производиться копирование экземпляра? Мне же нужно производить манипуляции с любым из переданных наследников конкретного класса.


N>Помнится, в с++ подобное я передавал указателями. Но в дот нете ведь нет указателей? Как быть в таком случае?


Будет производиться копирование ссылки (по С++ному — указателя). Экземпляр класса копироваться не будет. Копируются только структуры. В общем, почитай что-нибудь основополагающего. Например, вот это
--
Re[7]: Еще пара вопросов
От: Niovol  
Дата: 10.02.08 22:38
Оценка:
Здравствуйте, Сергей Туленцев, Вы писали:

СТ>Будет производиться копирование ссылки (по С++ному — указателя). Экземпляр класса копироваться не будет. Копируются только структуры. В общем, почитай что-нибудь основополагающего. Например, вот это


Ок, спасибо. Только на ссылку не выходит. Завтра поищу инфу. Плюс еще есть книжка от майкрософта по .NET, правда, 2003 года.
Re[8]: Еще пара вопросов
От: Сергей Туленцев Россия http://software.tulentsev.com
Дата: 11.02.08 05:23
Оценка:
Здравствуйте, Niovol, Вы писали:

N>Здравствуйте, Сергей Туленцев, Вы писали:


СТ>>Будет производиться копирование ссылки (по С++ному — указателя). Экземпляр класса копироваться не будет. Копируются только структуры. В общем, почитай что-нибудь основополагающего. Например, вот это


N>Ок, спасибо. Только на ссылку не выходит. Завтра поищу инфу. Плюс еще есть книжка от майкрософта по .NET, правда, 2003 года.


Это я ошибся. Вот что я хотел показать
--
Re[4]: Еще пара вопросов
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.02.08 05:55
Оценка:
Здравствуйте, Niovol, Вы писали:

N>Error 1 The best overloaded method match for 'NeuroV.Instructor.Instruct(ref NeuroV.Construction.Element)' has some invalid arguments

N>Error 2 Argument '1': cannot convert from 'ref NeuroV.Models.Perceptron' to 'ref NeuroV.Construction.Element'

Просто объяви переменную как Element. Это дотнетные тараканы связанные с передачей ref-параметров.

ЗЫ

Общий совет. В Немерле лучше вообще обходиться без ref-параметров. В нем есть tuple-ы (см. статьи и документацию). Они куда удобнее. Если возвращаемое значение одно, то его тоже имеет смысл возвращать прям из функции, а не делать out/ref.

Кстати, в дотнете большинство объектов ссылочные (не ссылочные только перечисления, структуры и встроенные типы вроде int). Передача из по ссылке только замедлит работу. Ну, и любое изменение состояния объекта будет видно внешней стороне. Единственное что не удастся сделать бещ ref — это изменить ссылку на переменную.

Так что почти на 100% уверен, что ref тебе не нужен.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Еще пара вопросов
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.02.08 06:06
Оценка:
Здравствуйте, Niovol, Вы писали:

N>Ок, т.е. по определению типы должны совпадать? А если все-таки нужно передать, передавать просто не по ссылке? Тогда будет производиться копирование экземпляра? Мне же нужно производить манипуляции с любым из переданных наследников конкретного класса.


N>Помнится, в с++ подобное я передавал указателями. Но в дот нете ведь нет указателей? Как быть в таком случае?


C++ более низкоуровневый язык. В C#/Nemerle все типы деляться на два основных подтипа:
1. Ссылочные типы — они всегда передаются по ссылке (как правильно заметил Сергей это почти (по крайней мере по эффективности) соответствует передаче указателя или по ссылке в С++.
2. Value-типы. Вот они всегда передаются по значению (т.е. коприуется память). Вот это аналогично передаче не по ссылке в С++. Вот для изменения их содержимого имеет нужно применять ref. Но оять же это не лучший выход. Лучше иметь вэлью-типы небольшого размера (до 16 байт) и передавать их по значению. Это сделает программы надежнее и не просадит производительность.

А вообще, тебе нужно почитать о семантике объекто в дотнете (о делении объектов на вылью-типы и на ссылочные типы). Очень хорошо об этом написано у Рихтера. В прочем в стеи описаний тоже достаточно. На нашем сайте, например, можно почитать:
http://www.rsdn.ru/article/dotnet/values.xml
Автор(ы): Андрей Мартынов
Дата: 08.04.2003
Начиная программировать в среде .Net, довольно часто сталкиваешься с трудностями, в основе которых лежит недостаточно чёткое понимание различий в свойствах ссылочных типов (reference based types) и типов-значений (value based types). Между тем, мотивация применять типы-значения велика, т.к. умелое применение типов-значений может существенно повысить эффективность программного кода. Однако необходимо постоянно помнить, что типы-значения имеют ряд особенностей, которые необходимо учитывать как при разработке (определении) этих типов, так и при их использовании. Эти особенности value-типов и их отличия от ссылочных типов рассмотрены ниже.

и http://www.rsdn.ru/article/dotnet/GC.xml
Автор(ы): Чистяков Влад (VladD2)
Дата: 14.06.2006
Уже много сказано слов о том, что такое GC, чем он хорош и как лучше его применять. Но, наверно, очень многим хочется знать, как устроен конкретный GC. Данная статья открывает некоторые подробности устройчтва GC в .NET Framework.
(но это уже для расширенного понимания работы с объектами).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Еще пара вопросов
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.02.08 06:10
Оценка:
Здравствуйте, Niovol, Вы писали:

N>Как я понял, немерле основан на функциональном подходе, а всякие циклы описаны макросами через вызовы функций.


Так и есть, но вызовы функций с концевой рекурсии оптимизируются и превращаются в код аналогичный циклам.

N>Если же, к примеру, пускать обычный for(mutable i...), не получится ли время исполнения больше, чем следует ожидать?


По крайней мере разница пренебрежима мала. Так что не забивай себе голову подобной фигней. Потери производительности надо искть не там.

N>У меня, кажется, на немерле программы работают по крайней мере в 2 раза дольше, чем на с++. Не знаю, дело в кривом написании кода, или на .NET жаловаться. Я как бы с .NET недавно столкнулся, до этого на чистом с++ программировал.


Это надо на программы смотреть. В дотете модули грузятся дольше, что часто вызвает впечатление заторможенности.

Лучше расскажи про свои задачи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Еще пара вопросов
От: Niovol  
Дата: 11.02.08 06:50
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Лучше расскажи про свои задачи.


Вот, там, где мне как раз критично время — это нейронные сети. Моя корявая программа на с++, на которую я грешил, на некоторых входных данных обучается где-то за 1.5 секунды. На тех же входных данных на немерле обучается секунды 3. Причем, как я думал, один кусок кода, который был не очень быстрым на с++, я на немерле написал по крайней мере лучше. Прога, которую пишу на немерле, не является копией сишной, но по смыслу выполняют все-таки одинаковые операции. Почему тут критично время — основной цикл проходит тысячи итераций, иногда десятки тысяч.
Re[4]: Еще пара вопросов
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.02.08 10:32
Оценка:
Здравствуйте, Niovol, Вы писали:

N>Вот, там, где мне как раз критично время — это нейронные сети. Моя корявая программа на с++, на которую я грешил, на некоторых входных данных обучается где-то за 1.5 секунды. На тех же входных данных на немерле обучается секунды 3. Причем, как я думал, один кусок кода, который был не очень быстрым на с++, я на немерле написал по крайней мере лучше. Прога, которую пишу на немерле, не является копией сишной, но по смыслу выполняют все-таки одинаковые операции. Почему тут критично время — основной цикл проходит тысячи итераций, иногда десятки тысяч.


В нейронных сетях не ничего не понимаю, так что конретных советов дать не смогу. Тут где-то советовали их описывать не объектами, а чем-то более примитивным.

Кроме того имеет смысл попробовать прогнать профайлер и поглядеть на что он показывает.

Десятки же и даже сотни тысяч проходов не так уж много, если конечно при этом на каждом проходе не выполняется какие-то долгие операции (например, создание объектов). Надо избегать такие опрации (по возможности) и стараться превычислять все что можно предварительно вычислить.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Еще пара вопросов
От: Niovol  
Дата: 11.02.08 14:14
Оценка:
VD>В нейронных сетях не ничего не понимаю, так что конретных советов дать не смогу. Тут где-то советовали их описывать не объектами, а чем-то более примитивным.
Вот именно это одно из соображений. Саму сеть и слои нейронов описал объектами, а нейроны — массивом чисел в классе слоя.
Только что возник вопрос, сколько времени идет доступ к произвольному элементу класса List[некоторый класс]? При том, что он содержит всего несколько экземпляров класса.
VD>Кроме того имеет смысл попробовать прогнать профайлер и поглядеть на что он показывает.
Как раз хотел спросить в предыдущем посте, как пользоваться профайлером, где можно почитать, к примеру. Я пробовал ставить VTune, но так и не разобрался, по инструкции не получалось.
VD>Десятки же и даже сотни тысяч проходов не так уж много, если конечно при этом на каждом проходе не выполняется какие-то долгие операции (например, создание объектов). Надо избегать такие опрации (по возможности) и стараться превычислять все что можно предварительно вычислить.
Нет, объекты создаются только в конструкторах. За одну итерацию по нескольку раз проходят вложенные циклы, поэтому, десятки тысяч итераций — уже значительно. А превычислять — это как?
Re[6]: Еще пара вопросов
От: Dr.Gigabit  
Дата: 12.02.08 05:49
Оценка:
Здравствуйте, Niovol, Вы писали:

VD>>В нейронных сетях не ничего не понимаю, так что конретных советов дать не смогу. Тут где-то советовали их описывать не объектами, а чем-то более примитивным.

N>Вот именно это одно из соображений. Саму сеть и слои нейронов описал объектами, а нейроны — массивом чисел в классе слоя.
N>Только что возник вопрос, сколько времени идет доступ к произвольному элементу класса List[некоторый класс]? При том, что он содержит всего несколько экземпляров класса.



А распараллеливать List не пробовал ? Воспользуйся прямой выгодой от функционального языка. Вот пример на F#. На Nemerle будет почти тоже самое.

[с#]
#light
namespace EeekSoft.FSharp

open System
open System.Threading

module Utils = begin

/// Same as List.fold_left function, but passes index of item in the list
/// as a first parameter to fold function
let list_fold_lefti (func:int -> 'a -> 'b -> 'a) (acc:'a) (l:'b list) =
let rec fli (func:int -> 'a -> 'b -> 'a) (acc:'a) (l:'b list) (n:int) =
match l with | [] -> acc | (h::t) -> fli func (func n acc h) t (n + 1)
fli func acc l 0;
end

module ParallelList = begin

/// Class that manages threads and executes operations in parallel
type ('a, 'b) ThreadProcessor = class
val threads : Thread array;
val worklist : 'a array;
val results : 'b array;
val result_states : int array;
val operation : 'a -> 'b;
val lock : obj;

val mutable position : int;
val mutable running : bool;
val mutable finished : int;

/// Accepts number of threads, array of input data and
/// mapping function as parameters
new((count:int), (arr:'a array), (func:'a -> 'b)) as t =
{
lock = new obj();
running = true;
worklist = arr;
results = Array.zero_create arr.Length;
result_states = Array.create arr.Length 0;
operation = func;
position = 0;
threads = Array.init count ( fun n -> new Thread(new ThreadStart(t.Process)) );
finished = 0;
}
then
t.threads |> Array.iter ( fun t -> t.Start() );

/// Stop execution and wait for all threads to complete
member t.Stop () =
t.running <- false;
t.threads |> Array.iter ( fun t -> t.Join() );

/// Private method executed by the thread(s)
member t.Process () =
// Get section in worklist that will be processed
let (sf, st) = Idioms.lock t.lock ( fun () ->
let len = t.worklist.Length;
if (t.position = len) then
t.running <- false; (1, 0)
else
let npos = t.position + (len — t.position) / (2*t.threads.Length);
let ret = (t.position, npos);
t.position <- npos + 1;
ret )
// Process section
for n = sf to st do
t.results.[n] <- (t.operation t.worklist.[n]);

// TODO: Interlocked.Exchange(~&(t.result_states.[n]), 1) |> ignore;
t.result_states.[n] <- 1;

done;
// Continue? tail-recursive...
if (t.running) then t.Process();

/// Reads results
/// TODO: it could be better to return Seq<'b>
member t.Results
with get() =
let mutable res = [] in
let max = (t.worklist.Length — 1)
let rec item n =
// TODO: Use Interlocked.Compare...
if (t.result_states.[n] = 0) then Thread.Sleep(10); item n; else t.results.[n];
for n = max downto 0 do
res <- (item n)::res;
done
res;
end

let mutable threadcount = 2
let get_thread_count () = threadcount
let set_thread_count n = threadcount <- n

let filter (func:'a -> bool) (lst:'a list) =
let arr = lst |> List.to_array;
let proc = new ThreadProcessor<'a, bool>(threadcount, arr, func)
let ret = proc.Results |> Utils.list_fold_lefti ( fun i acc v ->
match v with | true -> (arr.[i])::acc | false -> acc ) []
proc.Stop();
ret

let map (func:'a -> 'b) (lst:'a list) =
let arr = lst |> List.to_array;
let proc = new ThreadProcessor<'a, 'b>(threadcount, arr, func)
let ret = proc.Results
proc.Stop();
ret

end
[/c#]
... << RSDN@Home 1.2.0 alpha rev. 789>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.