Аналог Строки. Соединение (строка, строка []) для IEnumerable <T>

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

  1. Специальное HW, которое может обнаруживать значения, подобные адресам, в извлеченных строках кэша и выдавать предварительные выборки по этим адресам.
  2. Метод с использованием компилятора, при котором компилятор распознает зависимости структуры данных и вставляет предварительные выборки SW или другие подсказки.

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

Конечно, вам действительно нужно было бы работать на такой машине, так что это только теоретически, и вам не нужно менять свою практику, если она работает нормально для вас, но это показывает, что профилирование должно быть специфические для каждой микроархитектуры и системы, и то, что помогает вам в одном случае, может быть менее эффективным в другом.
Вообще говоря - не просто доверяйте ЦП выполнять или не выполнять некоторую оптимизацию (если она не задокументирована), всегда проверяйте, получаете ли вы ожидаемое поведение.

Кстати, обратите внимание, что даже если HW видит содержимое памяти, оно все еще находится в виртуальном адресном пространстве - HW в любом случае пришлось бы выполнить какой-то перевод в физический адрес, чтобы использовать его, так что в некотором смысле не должно быть никаких дополнительных накладных расходов.

Некоторая библиография:

7
задан abatishchev 18 April 2010 в 07:16
поделиться

6 ответов

Я написал метод расширения:

    public static IEnumerable<T> 
        Join<T>(this IEnumerable<T> src, Func<T> separatorFactory)
    {
        var srcArr = src.ToArray();
        for (int i = 0; i < srcArr.Length; i++)
        {
            yield return srcArr[i];
            if(i<srcArr.Length-1)
            {
                yield return separatorFactory();
            }
        }
    }

Вы можете использовать его следующим образом:

tableRowList.Join(()=>new TableRow())
8
ответ дан 6 December 2019 в 06:50
поделиться

Если бы я не мог найти метод, который соответствовал бы моим потребностям, я бы просто создал свой собственный. И методы расширения в этом плане очень хороши, поскольку позволяют расширять подобные вещи. Не очень разбираюсь в asp: table, но вот метод расширения, по крайней мере, вы можете настроить что угодно: p

public static class TableRowExtensions
{
    public string JoinRows(this IEnumerable<TableRow> rows, string separator)
    {
        // do what you gotta do
    }
}
1
ответ дан 6 December 2019 в 06:50
поделиться

Для этого нет встроенного метода, вы должны использовать свой собственный.

0
ответ дан 6 December 2019 в 06:50
поделиться

Если вы собираетесь делать подобные вещи часто, то для этого стоит создать собственный метод расширения. Реализация ниже позволяет вам сделать эквивалент string.Join (",", arrayOfStrings) , где arrayOfStrings может быть IEnumerable , а разделителем может быть любой объект в все. Это позволяет вам делать что-то вроде этого:

var names = new [] { "Fred", "Barney", "Wilma", "Betty" };
var list = names
    .Where(n => n.Contains("e"))
    .Join(", ");

Мне нравятся две вещи:

  1. Это очень удобно для чтения в контексте LINQ.
  2. Это довольно эффективно, поскольку использует StringBuilder и позволяет избежать повторной оценки перечисления.
public static string Join<TItem,TSep>(
    this IEnumerable<TItem> enuml,
    TSep                    separator)
{
    if (null == enuml) return string.Empty;

    var sb = new StringBuilder();

    using (var enumr = enuml.GetEnumerator())
    {
        if (null != enumr && enumr.MoveNext())
        {
            sb.Append(enumr.Current);
            while (enumr.MoveNext())
            {
                sb.Append(separator).Append(enumr.Current);
            }
        }
    }

    return sb.ToString();
}
0
ответ дан 6 December 2019 в 06:50
поделиться

В .NET 3.5 вы можете использовать этот метод расширения:

public static string Join<TItem>(this IEnumerable<TItem> enumerable, string separator)
{
   return string.Join(separator, enumerable.Select(x => x.ToString()).ToArray());
}

или в .NET 4

public static string Join<TItem>(this IEnumerable<TItem> enumerable, string separator)
{
   return string.Join(separator, enumerable);
}

, НО вопрос требовал разделителя после каждого элемента, включая последний, для которого эта (версия 3.5) будет работать: -

public static string AddDelimiterAfter<TItem>(this IEnumerable<TItem> enumerable, string delimiter)
{
   return string.Join("", enumerable.Select(x => x.ToString() + separator).ToArray());
}

Вы также можете использовать .Aggregate для этого без метода расширения .

7
ответ дан 6 December 2019 в 06:50
поделиться

Linq-эквивалент String.Join - Aggregate

Например:

IEnumerable<string> strings;
string joinedString = strings.Aggregate((total,next) => total + ", " + next);

Если задан IE TableRows, код будет аналогичным.

8
ответ дан 6 December 2019 в 06:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: