Самый быстрый вид массива интервала фиксированной длины 6

private void btnShowImage_Click(object sender, EventArgs e)
{
    string constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=.\\PIS(ACU).mdb;";
    Con = new OleDbConnection(@constr);
    Con.Open();
    Com = new OleDbCommand();
    Com.Connection = Con;     
    Com.CommandText = "SELECT Photo FROM PatientImages WHERE Patient_Id =  " + val + " ";
    OleDbDataReader reader = Com.ExecuteReader();
    if (reader.Read())
    {
        byte[] picbyte = reader["Photo"] as byte[] ?? null;
        if (picbyte != null)
        {
            MemoryStream mstream = new MemoryStream(picbyte);
            pictureBoxForImage.Image = System.Drawing.Image.FromStream(mstream);
        {
        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(mstream);
    }
}
395
задан 33 revs, 14 users 93% 8 April 2019 в 18:32
поделиться

3 ответа

Для любой оптимизации всегда лучше тестировать, тестировать, тестировать. Я бы попробовал по крайней мере сортировку сетей и сортировку вставкой. Если бы я делал ставку, я бы поставил на сортировку вставкой, основываясь на прошлом опыте.

Знаете ли вы что-нибудь о входных данных? Некоторые алгоритмы лучше работают с определенными типами данных. Например, сортировка вставкой лучше работает с отсортированными или почти отсортированными данными, поэтому она будет лучшим выбором, если вероятность наличия почти отсортированных данных выше среднего.

Алгоритм, который вы опубликовали, похож на сортировку вставкой, но похоже, что вы минимизировали количество свопов ценой большего количества сравнений. Однако сравнения намного дороже, чем замены, потому что ветвления могут привести к остановке конвейера команд.

Вот реализация сортировки вставкой:

static __inline__ int sort6(int *d){
        int i, j;
        for (i = 1; i < 6; i++) {
                int tmp = d[i];
                for (j = i; j >= 1 && tmp < d[j-1]; j--)
                        d[j] = d[j-1];
                d[j] = tmp;
        }
}

Вот как я бы построил сеть сортировки. Во-первых, используйте этот сайт для генерации минимального набора SWAP-макросов для сети соответствующей длины. Завернув это в функцию, я получаю:

static __inline__ int sort6(int * d){
#define SWAP(x,y) if (d[y] < d[x]) { int tmp = d[x]; d[x] = d[y]; d[y] = tmp; }
    SWAP(1, 2);
    SWAP(0, 2);
    SWAP(0, 1);
    SWAP(4, 5);
    SWAP(3, 5);
    SWAP(3, 4);
    SWAP(0, 3);
    SWAP(1, 4);
    SWAP(2, 5);
    SWAP(2, 4);
    SWAP(1, 3);
    SWAP(2, 3);
#undef SWAP
}
160
ответ дан 22 November 2019 в 23:43
поделиться

Поскольку это целые числа и сравнение выполняется быстро, почему бы не вычислить ранговый порядок каждого из них напрямую:

inline void sort6(int *d) {
  int e[6];
  memcpy(e,d,6*sizeof(int));
  int o0 = (d[0]>d[1])+(d[0]>d[2])+(d[0]>d[3])+(d[0]>d[4])+(d[0]>d[5]);
  int o1 = (d[1]>=d[0])+(d[1]>d[2])+(d[1]>d[3])+(d[1]>d[4])+(d[1]>d[5]);
  int o2 = (d[2]>=d[0])+(d[2]>=d[1])+(d[2]>d[3])+(d[2]>d[4])+(d[2]>d[5]);
  int o3 = (d[3]>=d[0])+(d[3]>=d[1])+(d[3]>=d[2])+(d[3]>d[4])+(d[3]>d[5]);
  int o4 = (d[4]>=d[0])+(d[4]>=d[1])+(d[4]>=d[2])+(d[4]>=d[3])+(d[4]>d[5]);
  int o5 = 15-(o0+o1+o2+o3+o4);
  d[o0]=e[0]; d[o1]=e[1]; d[o2]=e[2]; d[o3]=e[3]; d[o4]=e[4]; d[o5]=e[5];
}
44
ответ дан 22 November 2019 в 23:43
поделиться

Вот реализация с использованием сортировочных сетей:

inline void Sort2(int *p0, int *p1)
{
    const int temp = min(*p0, *p1);
    *p1 = max(*p0, *p1);
    *p0 = temp;
}

inline void Sort3(int *p0, int *p1, int *p2)
{
    Sort2(p0, p1);
    Sort2(p1, p2);
    Sort2(p0, p1);
}

inline void Sort4(int *p0, int *p1, int *p2, int *p3)
{
    Sort2(p0, p1);
    Sort2(p2, p3);
    Sort2(p0, p2);  
    Sort2(p1, p3);  
    Sort2(p1, p2);  
}

inline void Sort6(int *p0, int *p1, int *p2, int *p3, int *p4, int *p5)
{
    Sort3(p0, p1, p2);
    Sort3(p3, p4, p5);
    Sort2(p0, p3);  
    Sort2(p2, p5);  
    Sort4(p1, p2, p3, p4);  
}

Для этого действительно нужны очень эффективные реализации без ветвления min и max, поскольку это фактически то, к чему сводится данный код - последовательность операций min и max (всего 13 операций). Я оставляю это в качестве упражнения для читателя.

Обратите внимание, что эта реализация легко поддается векторизации (например, SIMD - большинство SIMD ISA имеют векторные инструкции min/max), а также реализации на GPU (например, CUDA - поскольку она не имеет ветвлений, нет проблем с расхождением искривлений и т.д.).

См. также: Быстрая реализация алгоритма для сортировки очень маленького списка

60
ответ дан 22 November 2019 в 23:43
поделиться
Другие вопросы по тегам:

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