Есть ли у кого опыт решения такой проблемы:
в библиотеке А (пусть это для конкретики будет Monogame) есть тип Vector2.
в библиотеки B (ну к примеру порт какого нить физ движка на шарп) — второй свой Vector или Point.
.NET эти два типа понимает как разные и конечно не может позволить ни приведение ни присваивание одного к другому.
Иногда спасает пересоздавание на манер v = new Vector2(p.x,py).
Но это в простейших случаях.
Проблема то глобальнее. На С/C++ это проще обойти указателями или копированием.
Есть какие то перспективы решения этой проблемы в c#70?
Re: Портирование типов между различными библиотеками
Здравствуйте, barn_czn, Вы писали:
_>Проблема то глобальнее. На С/C++ это проще обойти указателями или копированием.
Одна из причин, по которой я с радостью забыл о C/C++ — необходимость "женить" разные библиотеки из-за разных типов данных.
_>Есть какие то перспективы решения этой проблемы в c#70?
Сделай методы-расширения .ToVector2() и .ToVector().
Re[2]: Портирование типов между различными библиотеками
Здравствуйте, Vladek, Вы писали:
_>>Проблема то глобальнее. На С/C++ это проще обойти указателями или копированием. V> Одна из причин, по которой я с радостью забыл о C/C++ — необходимость "женить" разные библиотеки из-за разных типов данных.
_>>Есть какие то перспективы решения этой проблемы в c#70? V>Сделай методы-расширения .ToVector2() и .ToVector().
Здравствуйте, barn_czn, Вы писали:
_>.NET эти два типа понимает как разные и конечно не может позволить ни приведение ни присваивание одного к другому. _>Иногда спасает пересоздавание на манер v = new Vector2(p.x,py). _>Но это в простейших случаях.
Норм. вариант. C# же оч. строго типизированный. Две разные либы — два разых типа-два разных объекта.
_>Проблема то глобальнее. На С/C++ это проще обойти указателями или копированием. _>Есть какие то перспективы решения этой проблемы в c#70?
А потом, при обновлении одной из либ.,- иметь пролемы в коде, потому что в одной из либ. тип изменился.
Підтримати Україну у боротьбі з країною-терористом.
Здравствуйте, Vladek, Вы писали:
V>Здравствуйте, barn_czn, Вы писали:
_>>Проблема то глобальнее. На С/C++ это проще обойти указателями или копированием. V> Одна из причин, по которой я с радостью забыл о C/C++ — необходимость "женить" разные библиотеки из-за разных типов данных.
Эта возможность "женить" разные либы наоборот повысило в моих глазах С/C++ и принизило шарп. Конечно я все понимаю что строгая типизация бла бла.. но есть суровая реальность.
_>>Есть какие то перспективы решения этой проблемы в c#70? V>Сделай методы-расширения .ToVector2() и .ToVector().
И чем они помогут? Не надо путать синтаксический сахар с проблемой конверта без потери перфоманса.
Re[2]: Портирование типов между различными библиотеками
Здравствуйте, #John, Вы писали:
J>Здравствуйте, barn_czn, Вы писали:
_>>.NET эти два типа понимает как разные и конечно не может позволить ни приведение ни присваивание одного к другому. _>>Иногда спасает пересоздавание на манер v = new Vector2(p.x,py). _>>Но это в простейших случаях. J>Норм. вариант. C# же оч. строго типизированный. Две разные либы — два разых типа-два разных объекта.
да это все понятно.. но для плоских структур, к примеру, можно бы было чтото придумать декларативное и простое, без привлечения unsafe.
_>>Проблема то глобальнее. На С/C++ это проще обойти указателями или копированием. _>>Есть какие то перспективы решения этой проблемы в c#70? J>А потом, при обновлении одной из либ.,- иметь пролемы в коде, потому что в одной из либ. тип изменился.
Вы итак будете иметь эти боли, хотя бы в виде ошибок компиляции. Я как раз и жду такого решения чтобы компилятор контролировал эти изменения, и в тоже время позволял делать легкий конверт структур.
Re: Портирование типов между различными библиотеками
Здравствуйте, barn_czn, Вы писали:
_>Есть какие то перспективы решения этой проблемы в c#70?
Заведите соответствующую ишью в гитхабе розлина и попробуйте убедить местных, что без этого шарп не интересен, а не то и вправду только к семидесятой версии до такой полезной фичи додумаются.
Re[3]: Портирование типов между различными библиотеками
Здравствуйте, barn_czn, Вы писали:
_>Эта возможность "женить" разные либы наоборот повысило в моих глазах С/C++ и принизило шарп. Конечно я все понимаю что строгая типизация бла бла.. но есть суровая реальность.
В суровой реальности проблемы вроде описанной встречаются редко, библиотеки пользуются общей системой базовых типов и необходимости конвертировать данные на каждом шагу нет. Из С++ я помню стопицот классов работы со строками.
_>>>Есть какие то перспективы решения этой проблемы в c#70? V>>Сделай методы-расширения .ToVector2() и .ToVector().
_>И чем они помогут? Не надо путать синтаксический сахар с проблемой конверта без потери перфоманса.
Не надо беспокоиться о потери "перформанса" без профайлера, потом, если понадобится, перепишешь эти методы с учётом "перформанса". Главное, код преобразования типов надо будет менять только в этих двух методах.
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте, barn_czn, Вы писали:
_>>Проблема то глобальнее. На С/C++ это проще обойти указателями или копированием. _>>Есть какие то перспективы решения этой проблемы в c#70?
S>Чем это не подходит -- https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx ?
это снова синтакс. сахар маскирующий проблему.
пример: Dot(ref Vector2d a, ref Vector2d b) — и все, попрут лишние копирования которые сведут на нет весь ref
Re: Портирование типов между различными библиотеками
Здравствуйте, barn_czn, Вы писали:
_>Есть ли у кого опыт решения такой проблемы: _>в библиотеке А (пусть это для конкретики будет Monogame) есть тип Vector2. _>в библиотеки B (ну к примеру порт какого нить физ движка на шарп) — второй свой Vector или Point.
Я бы захачил порт физ движка B так, чтобы он использовал типы из А. Ну или наоборот (смотря какие исходники доступны, и смотря что проще, если доступны обе). Типы, представляющие одинаковые сущности, имеют тенденцию иметь схожие юзкейсы и, следовательно, API, потому обычно несложно "привести к общему знаменателю".
K>Я бы захачил порт физ движка B так, чтобы он использовал типы из А. Ну или наоборот (смотря какие исходники доступны, и смотря что проще, если доступны обе).
Этот колхоз рассыпается после правки структуры в любом из проектов.
Впрочем, иногда даже правок не требуется. Одни горячие финские парни решили, что можно безопасно использовать магию типа такой (спасибо SO за готовый пример):
var ch4 = new Chapter4Time { TimeLow = 100, MicroSeconds = 50 };
var ieee1588 = *((IEEE_1588Time*) &ch4);
Console.WriteLine(ieee1588.Seconds);
long story short — они не угадали. Чуть поподробее — LayoutKind.Auto работает именно так, как написано.
Правильный способ — или extension methods|операторы для перевода типов, или запрос в библиотеку на тему выноса базовых типов в отдельную библиотеку.
Re[3]: Портирование типов между различными библиотеками
Здравствуйте, Sinix, Вы писали:
S>Этот колхоз рассыпается после правки структуры в любом из проектов.
Сразу видно теоретика (без обид). Я даже опишу, как ты прочитал вопрос — "У меня есть либы А и B с некими классами, имеющими одинаковое значение. Как их подружить?" Так?
Ну а теперь сходи и прочитай, что там на самом деле написано
S>Правильный способ — или extension methods|операторы для перевода типов, или запрос в библиотеку на тему выноса базовых типов в отдельную библиотеку.
И получить 1 фрейм в год
Здравствуйте, koandrew, Вы писали:
K>Ну а теперь сходи и прочитай, что там на самом деле написано
Так не имеет оно общего решения. Если конечно не считать за решение патчинг сборок с подменой типов.
S>>Правильный способ — или extension methods|операторы для перевода типов, или запрос в библиотеку на тему выноса базовых типов в отдельную библиотеку. K>И получить 1 фрейм в год
А вот троллить надо умеючи и желательно перед этим сходив в разведку
Потому что мсье немножко так практик и в курсе, что обычный расклад для x86 выглядит примерно так:
Копейки даже по сравнению с вызовом метода. Если вам даже на таком приходится экономить, то всяко лучше вытащить код в натив и не трепать бабушку по мелочам
код
using System;
using System.Diagnostics;
using System.Diagnostics.SymbolStore;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace CodeDrafts
{
static class Program
{
struct A
{
public uint a1;
public uint a2;
}
struct B
{
public ulong b1;
}
static B FromA(A a)
{
return new B { b1 = (ulong)a.a1 << 32 | a.a2 };
}
unsafe static B FromAUnsafe(A a)
{
return *(B*)&a;
}
[MethodImpl(MethodImplOptions.NoInlining)]
unsafe static B FromAUnsafeNotInlined(A a)
{
return *(B*)&a;
}
static void Main(string[] args)
{
Console.WindowWidth = 120;
const int Count = 100*1000*1000;
Measure("Naive", () =>
{
var a = new A();
var b = new B();
for (int i = 0; i < Count; i++)
{
b = FromA(a);
}
GC.KeepAlive(b);
return Count;
});
Measure("Unsafe", () =>
{
var a = new A();
var b = new B();
for (int i = 0; i < Count; i++)
{
b = FromAUnsafe(a);
}
GC.KeepAlive(b);
return Count;
});
Measure("UnsafeNotInlined", () =>
{
var a = new A();
var b = new B();
for (int i = 0; i < Count; i++)
{
b = FromAUnsafeNotInlined(a);
}
GC.KeepAlive(b);
return Count;
});
Console.Write("Done...");
Console.ReadKey();
}
private static void Measure(string name, Func<long> callback)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
var mem = GC.GetTotalMemory(true);
var gc00 = GC.CollectionCount(0);
var gc01 = GC.CollectionCount(1);
var gc02 = GC.CollectionCount(2);
var sw = Stopwatch.StartNew();
var result = callback();
sw.Stop();
var mem2 = GC.GetTotalMemory(false);
var gc10 = GC.CollectionCount(0);
var gc11 = GC.CollectionCount(1);
var gc12 = GC.CollectionCount(2);
var memDelta = (mem2 - mem)/1024.0;
var gcDelta0 = gc10 - gc00;
var gcDelta1 = gc11 - gc01;
var gcDelta2 = gc12 - gc02;
Console.WriteLine(
"{0,20}: {1,5}ms, ips: {2,22:N} | Mem: {3,9:N2} kb, GC 0/1/2: {4}/{5}/{6} => {7,6}",
name, sw.ElapsedMilliseconds, result/sw.Elapsed.TotalSeconds, memDelta, gcDelta0, gcDelta1, gcDelta2, result);
}
}
}
P.S. В качестве бонуса — попробуйте объяснить поведение с закомментированным GC.KeepAlive(b);
Здравствуйте, Sinix, Вы писали: S>P.S. В качестве бонуса — попробуйте объяснить поведение с закомментированным GC.KeepAlive(b);
Правильно понимаю (ildasm-ом крути), что вместе с GC.KA в стеке создастся одна переменная и память под неё будет переиспользоваться, в то время как без GC.KA будет оптимизатор (он?) выкинет переменную и будет постоянно выделяться/освобождаться память в стеке под значение?
Re[6]: Портирование типов между различными библиотеками
Здравствуйте, vasmann, Вы писали:
V>Здравствуйте, Sinix, Вы писали: S>>P.S. В качестве бонуса — попробуйте объяснить поведение с закомментированным GC.KeepAlive(b);
V>Правильно понимаю (ildasm-ом крути), что вместе с GC.KA в стеке создастся одна переменная и память под неё будет переиспользоваться, в то время как без GC.KA будет оптимизатор (он?) выкинет переменную и будет постоянно выделяться/освобождаться память в стеке под значение?
Кстати, если вместо KA сделать Console.WriteLine(b.b1); //Смысл — используем переменную то результаты еще больше улучшаются
GC.KeepAlive(b)
Здравствуйте, vasmann, Вы писали:
V>Кстати, если вместо KA сделать Console.WriteLine(b.b1); //Смысл — используем переменную то результаты еще больше улучшаются
Дополню: "улучшились" не совсем корректное слово, стали отображать реальность — исключили время на боксинг объекта.
Re[7]: Портирование типов между различными библиотеками
Здравствуйте, vasmann, Вы писали:
V>Кстати, если вместо KA сделать Console.WriteLine(b.b1); //Смысл — используем переменную то результаты еще больше улучшаются
Угу. Сорри, не заметил сразу ответа.