Сообщение Re[39]: Есть ли подобие LINQ на других языках/платформах? от 24.04.2021 11:55
Изменено 28.07.2021 7:58 Serginio1
Re[39]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Ikemefula, Вы писали:
I>То есть, если ты сотню раз будешь использовать источник такого вида
I>
I>То ты сэкономишь кучу памяти, но при этом работа с источником окажется примерно в 1000 раз медленнее.
I>И для оптимизации используется кеширование коллекции.
Специально сделал тест
727,6487
576460750692810753
576460750692810753
6389,199
отношение yield к inline 8,780609379223794
То есть ты ошибся как минимум раз в 100! Ну какая хрен разница подумаешь! Главное медленнее. Но цифрами бросаться все же не стоит.
И это на result += i; Если будут функции с поиском в хэштаблице и ли функции работы со строками,
а учитывая, что в реалии нужно обращаться к данным, которые могут находиться вне кэша памяти, то это отношение будет стремиться к 1!!
То есть ни о каких 1000 и близко нет, но вот если тебе понадобится коллекция то ты на памяти больше потеряешь.
А что мне кэшировать если
1. Данные меняются
2. Мне нужно один раз получить такой итератор с такими условиями.
Кстати в .Net появился ref return
И получать Current по ссылке
и вызов
То получим
576460750692810753
3235,4582
отношение RefResult к inline 4,327135105321729
То есть ошибся всего в 250 раз!!
Ну в MS считают, что это не принципиально
Но к сожалению такая конструкция
Ругается на ref int res = ref iter.ReturnResult();
Итераторы не могут иметь переменные по ссылке
Но если заменить MoveNext
И вызов
То получим
576460750692810753
3420,4316
отношение RefResult к inline 4,805504333751022
Можно безболезненно и сейчас увеличит производительность, если все итераторы будут наследоваться от одного класса
public class MyIterator<T>
{
public T Result = default(t);
И вызов
Тогда отношение будет всего 3,530814317127427
То есть ошибся ты всего в 300 раз.
Вот и верь тебе!!
Ну не нужно это MS
I>То есть, если ты сотню раз будешь использовать источник такого вида
I>
I>while(true) {
I> yield i++;
I>}
I>
I>То ты сэкономишь кучу памяти, но при этом работа с источником окажется примерно в 1000 раз медленнее.
I>И для оптимизации используется кеширование коллекции.
Специально сделал тест
class Program
{
static long InlineCalk()
{
long result = 0;
for (int i = 0; i < int.MaxValue/2; i++)
result += i;
return result;
}
static IEnumerable<int> GetEnumerable()
{
for (int i = 0; i < int.MaxValue/2; i++)
yield return i;
}
static long YieldCalk()
{
long result = 0;
foreach (int i in GetEnumerable())
result += i;
return result;
}
static void Main(string[] args)
{
var r = DateTime.Now;
var result=InlineCalk();
var res = (DateTime.Now - r).TotalMilliseconds;
Console.WriteLine(res);
Console.WriteLine(result);
r = DateTime.Now;
result=YieldCalk();
var res2 = (DateTime.Now - r).TotalMilliseconds;
Console.WriteLine(result);
Console.WriteLine(res2);
Console.WriteLine($"отношение yield к inline {res2 / res}");
Console.ReadLine();
}
}
727,6487
576460750692810753
576460750692810753
6389,199
отношение yield к inline 8,780609379223794
То есть ты ошибся как минимум раз в 100! Ну какая хрен разница подумаешь! Главное медленнее. Но цифрами бросаться все же не стоит.
И это на result += i; Если будут функции с поиском в хэштаблице и ли функции работы со строками,
а учитывая, что в реалии нужно обращаться к данным, которые могут находиться вне кэша памяти, то это отношение будет стремиться к 1!!
То есть ни о каких 1000 и близко нет, но вот если тебе понадобится коллекция то ты на памяти больше потеряешь.
А что мне кэшировать если
1. Данные меняются
2. Мне нужно один раз получить такой итератор с такими условиями.
Кстати в .Net появился ref return
public class MyIterator
{
int Result = 0;
int state = 0;
public ref int ReturnResult()
{
return ref Result;
}
public bool MoveNext()
{
switch (this.state)
{
case 0:
Result = 0;
state = 1;
return true;
case 1:
Result++;
if (Result == int.MaxValue / 2)
{
state = 3;
return false;
}
return true;
default:
return false;
}
}
}
И получать Current по ссылке
static long RefResult()
{
long result = 0;
var iter = new MyIterator();
ref int res = ref iter.ReturnResult();
while (iter.MoveNext())
result += res;
return result;
}
и вызов
r = DateTime.Now;
result = RefResult();
var res3 = (DateTime.Now - r).TotalMilliseconds;
Console.WriteLine(result);
Console.WriteLine(res3);
Console.WriteLine($"отношение RefResult к inline {res3 / res}");
То получим
576460750692810753
3235,4582
отношение RefResult к inline 4,327135105321729
То есть ошибся всего в 250 раз!!
Ну в MS считают, что это не принципиально
Но к сожалению такая конструкция
static IEnumerable<int> GetEnumerable2()
{
var iter = new MyIterator();
ref int res = ref iter.ReturnResult();
while (iter.MoveNext())
yield return res;
}
Ругается на ref int res = ref iter.ReturnResult();
Итераторы не могут иметь переменные по ссылке
Но если заменить MoveNext
public bool MoveNext2(ref int result)
{
switch (this.state)
{
case 0:
Result = 0;
state = 1;
return true;
case 1:
Result++;
if (Result == int.MaxValue / 2)
{
state = 3;
return false;
}
result = Result;
return true;
default:
return false;
}
}
И вызов
static long RefResult2()
{
long result = 0;
var iter = new MyIterator();
int res = 0;
while (iter.MoveNext2(ref res))
result += res;
return result;
}
То получим
576460750692810753
3420,4316
отношение RefResult к inline 4,805504333751022
Можно безболезненно и сейчас увеличит производительность, если все итераторы будут наследоваться от одного класса
public class MyIterator<T>
{
public T Result = default(t);
И вызов
static long RefResult3()
{
long result = 0;
var iter = new MyIterator();
int res = 0;
while (iter.MoveNext())
result += iter.Result;
return result;
}
Тогда отношение будет всего 3,530814317127427
То есть ошибся ты всего в 300 раз.
Вот и верь тебе!!
Ну не нужно это MS
Re[39]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Ikemefula, Вы писали:
I>То есть, если ты сотню раз будешь использовать источник такого вида
I>
I>То ты сэкономишь кучу памяти, но при этом работа с источником окажется примерно в 1000 раз медленнее.
I>И для оптимизации используется кеширование коллекции.
Специально сделал тест
727,6487
576460750692810753
576460750692810753
6389,199
отношение yield к inline 8,780609379223794
То есть ты ошибся как минимум раз в 100! Ну какая хрен разница подумаешь! Главное медленнее. Но цифрами бросаться все же не стоит.
И это на result += i; Если будут функции с поиском в хэштаблице и ли функции работы со строками,
а учитывая, что в реалии нужно обращаться к данным, которые могут находиться вне кэша памяти, то это отношение будет стремиться к 1!!
То есть ни о каких 1000 и близко нет, но вот если тебе понадобится коллекция то ты на памяти больше потеряешь.
А что мне кэшировать если
1. Данные меняются
2. Мне нужно один раз получить такой итератор с такими условиями.
Кстати в .Net появился ref return
И получать Current по ссылке
и вызов
То получим
576460750692810753
3235,4582
отношение RefResult к inline 4,327135105321729
То есть ошибся всего в 250 раз!!
Ну в MS считают, что это не принципиально
Но к сожалению такая конструкция
Ругается на ref int res = ref iter.ReturnResult();
Итераторы не могут иметь переменные по ссылке
Но если заменить MoveNext
И вызов
То получим
576460750692810753
3420,4316
отношение RefResult к inline 4,805504333751022
Можно безболезненно и сейчас увеличит производительность, если все итераторы будут наследоваться от одного класса
И вызов
Тогда отношение будет всего 3,530814317127427
То есть ошибся ты всего в 300 раз.
Вот и верь тебе!!
Ну не нужно это MS
I>То есть, если ты сотню раз будешь использовать источник такого вида
I>
I>while(true) {
I> yield i++;
I>}
I>
I>То ты сэкономишь кучу памяти, но при этом работа с источником окажется примерно в 1000 раз медленнее.
I>И для оптимизации используется кеширование коллекции.
Специально сделал тест
class Program
{
static long InlineCalk()
{
long result = 0;
for (int i = 0; i < int.MaxValue/2; i++)
result += i;
return result;
}
static IEnumerable<int> GetEnumerable()
{
for (int i = 0; i < int.MaxValue/2; i++)
yield return i;
}
static long YieldCalk()
{
long result = 0;
foreach (int i in GetEnumerable())
result += i;
return result;
}
static void Main(string[] args)
{
var r = DateTime.Now;
var result=InlineCalk();
var res = (DateTime.Now - r).TotalMilliseconds;
Console.WriteLine(res);
Console.WriteLine(result);
r = DateTime.Now;
result=YieldCalk();
var res2 = (DateTime.Now - r).TotalMilliseconds;
Console.WriteLine(result);
Console.WriteLine(res2);
Console.WriteLine($"отношение yield к inline {res2 / res}");
Console.ReadLine();
}
}
727,6487
576460750692810753
576460750692810753
6389,199
отношение yield к inline 8,780609379223794
То есть ты ошибся как минимум раз в 100! Ну какая хрен разница подумаешь! Главное медленнее. Но цифрами бросаться все же не стоит.
И это на result += i; Если будут функции с поиском в хэштаблице и ли функции работы со строками,
а учитывая, что в реалии нужно обращаться к данным, которые могут находиться вне кэша памяти, то это отношение будет стремиться к 1!!
То есть ни о каких 1000 и близко нет, но вот если тебе понадобится коллекция то ты на памяти больше потеряешь.
А что мне кэшировать если
1. Данные меняются
2. Мне нужно один раз получить такой итератор с такими условиями.
Кстати в .Net появился ref return
public class MyIterator
{
int Result = 0;
int state = 0;
public ref int ReturnResult()
{
return ref Result;
}
public bool MoveNext()
{
switch (this.state)
{
case 0:
Result = 0;
state = 1;
return true;
case 1:
Result++;
if (Result == int.MaxValue / 2)
{
state = 3;
return false;
}
return true;
default:
return false;
}
}
}
И получать Current по ссылке
static long RefResult()
{
long result = 0;
var iter = new MyIterator();
ref int res = ref iter.ReturnResult();
while (iter.MoveNext())
result += res;
return result;
}
и вызов
r = DateTime.Now;
result = RefResult();
var res3 = (DateTime.Now - r).TotalMilliseconds;
Console.WriteLine(result);
Console.WriteLine(res3);
Console.WriteLine($"отношение RefResult к inline {res3 / res}");
То получим
576460750692810753
3235,4582
отношение RefResult к inline 4,327135105321729
То есть ошибся всего в 250 раз!!
Ну в MS считают, что это не принципиально
Но к сожалению такая конструкция
static IEnumerable<int> GetEnumerable2()
{
var iter = new MyIterator();
ref int res = ref iter.ReturnResult();
while (iter.MoveNext())
yield return res;
}
Ругается на ref int res = ref iter.ReturnResult();
Итераторы не могут иметь переменные по ссылке
Но если заменить MoveNext
public bool MoveNext2(ref int result)
{
switch (this.state)
{
case 0:
Result = 0;
state = 1;
return true;
case 1:
Result++;
if (Result == int.MaxValue / 2)
{
state = 3;
return false;
}
result = Result;
return true;
default:
return false;
}
}
И вызов
static long RefResult2()
{
long result = 0;
var iter = new MyIterator();
int res = 0;
while (iter.MoveNext2(ref res))
result += res;
return result;
}
То получим
576460750692810753
3420,4316
отношение RefResult к inline 4,805504333751022
Можно безболезненно и сейчас увеличит производительность, если все итераторы будут наследоваться от одного класса
public class MyIterator<T>
{
public T Result = default(t);
И вызов
static long RefResult3()
{
long result = 0;
var iter = new MyIterator();
int res = 0;
while (iter.MoveNext())
result += iter.Result;
return result;
}
Тогда отношение будет всего 3,530814317127427
То есть ошибся ты всего в 300 раз.
Вот и верь тебе!!
Ну не нужно это MS