Skip to content

Commit

Permalink
pixops: Replace shellsort with radix sort
Browse files Browse the repository at this point in the history
Enabled by the fact that color channels are now guaranteed to be
8-bit. Improves symbol conversion speed by over 20% in my tests.
  • Loading branch information
hpjansson committed Feb 5, 2024
1 parent 40039ae commit c743dbd
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 38 deletions.
41 changes: 12 additions & 29 deletions chafa/internal/chafa-pixops.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,38 +798,21 @@ chafa_prepare_pixel_data_for_symbols (const ChafaPalette *palette,
void
chafa_sort_pixel_index_by_channel (guint8 *index, const ChafaPixel *pixels, gint n_pixels, gint ch)
{
const gint gaps [] = { 57, 23, 10, 4, 1 };
gint g, i, j;
guint8 buckets [256] [64];
guint8 bucket_size [256] = { 0 };
gint i, j, k;

/* Since we don't care about stability and the number of elements
* is small and known in advance, use a simple in-place shellsort.
*
* Due to locality and callback overhead this is probably faster
* than qsort(), although admittedly I haven't benchmarked it.
*
* Another option is to use radix, but since we support multiple
* color spaces with fixed-point reals, we could get more buckets
* than is practical. */
g_assert (n_pixels <= 64);

for (g = 0; ; g++)
for (i = 0; i < n_pixels; i++)
{
gint gap = gaps [g];

for (i = gap; i < n_pixels; i++)
{
guint8 ptemp = index [i];

for (j = i; j >= gap && pixels [index [j - gap]].col.ch [ch]
> pixels [ptemp].col.ch [ch]; j -= gap)
{
index [j] = index [j - gap];
}

index [j] = ptemp;
}
guint8 bucket = pixels [i].col.ch [ch];
buckets [bucket] [bucket_size [bucket]++] = i;
}

/* After gap == 1 the array is always left sorted */
if (gap == 1)
break;
for (i = 0, k = 0; i < 256; i++)
{
for (j = 0; j < bucket_size [i]; j++)
index [k++] = buckets [i] [j];
}
}
9 changes: 0 additions & 9 deletions chafa/internal/chafa-work-cell.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,22 +163,13 @@ static const guint8 *
work_cell_get_sorted_pixels (ChafaWorkCell *wcell, gint ch)
{
guint8 *index;
const guint8 index_init [CHAFA_SYMBOL_N_PIXELS] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
};

index = &wcell->pixels_sorted_index [ch] [0];

if (wcell->have_pixels_sorted_by_channel [ch])
return index;

memcpy (index, index_init, CHAFA_SYMBOL_N_PIXELS);
chafa_sort_pixel_index_by_channel (index, wcell->pixels, CHAFA_SYMBOL_N_PIXELS, ch);

wcell->have_pixels_sorted_by_channel [ch] = TRUE;
return index;
}
Expand Down

0 comments on commit c743dbd

Please sign in to comment.