mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +00:00
libsysprof: sort frames with timsort
These are largely pre-sorted, but not fully when you have merged data. This uses timsort to speed that up a bit. In particular, the comparison of various sorts break down to (for a ~32,000,000 record capture. g_array_sort_with_data() => 3.9 seconds qsort_r() = > 3.7 seconds gtk_tim_sort() => .79 seconds
This commit is contained in:
120
src/libsysprof/timsort/gtktimsortprivate.h
Normal file
120
src/libsysprof/timsort/gtktimsortprivate.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright © 2020 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
/* The maximum number of entries in a GtkTimState's pending-runs stack.
|
||||
* This is enough to sort arrays of size up to about
|
||||
* 32 * phi ** GTK_TIM_SORT_MAX_PENDING
|
||||
* where phi ~= 1.618. 85 is ridiculously large enough, good for an array
|
||||
* with 2**64 elements.
|
||||
*/
|
||||
#define GTK_TIM_SORT_MAX_PENDING 86
|
||||
|
||||
typedef struct _GtkTimSort GtkTimSort;
|
||||
typedef struct _GtkTimSortRun GtkTimSortRun;
|
||||
|
||||
struct _GtkTimSortRun
|
||||
{
|
||||
void *base;
|
||||
gsize len;
|
||||
};
|
||||
|
||||
struct _GtkTimSort
|
||||
{
|
||||
/*
|
||||
* Size of elements. Used to decide on fast paths.
|
||||
*/
|
||||
gsize element_size;
|
||||
|
||||
/* The comparator for this sort.
|
||||
*/
|
||||
GCompareDataFunc compare_func;
|
||||
gpointer data;
|
||||
|
||||
/*
|
||||
* The array being sorted.
|
||||
*/
|
||||
gpointer base;
|
||||
gsize size;
|
||||
|
||||
/*
|
||||
* The maximum size of a merge. It's guaranteed >0 and user-provided.
|
||||
* See the comments for gtk_tim_sort_set_max_merge_size() for details.
|
||||
*/
|
||||
gsize max_merge_size;
|
||||
|
||||
/*
|
||||
* This controls when we get *into* galloping mode. It is initialized
|
||||
* to MIN_GALLOP. The mergeLo and mergeHi methods nudge it higher for
|
||||
* random data, and lower for highly structured data.
|
||||
*/
|
||||
gsize min_gallop;
|
||||
|
||||
/*
|
||||
* The minimum run length. See compute_min_run() for details.
|
||||
*/
|
||||
gsize min_run;
|
||||
|
||||
/*
|
||||
* Temp storage for merges.
|
||||
*/
|
||||
void *tmp;
|
||||
gsize tmp_length;
|
||||
|
||||
/*
|
||||
* A stack of pending runs yet to be merged. Run i starts at
|
||||
* address base[i] and extends for len[i] elements. It's always
|
||||
* true (so long as the indices are in bounds) that:
|
||||
*
|
||||
* runBase[i] + runLen[i] == runBase[i + 1]
|
||||
*
|
||||
* so we could cut the storage for this, but it's a minor amount,
|
||||
* and keeping all the info explicit simplifies the code.
|
||||
*/
|
||||
gsize pending_runs; // Number of pending runs on stack
|
||||
GtkTimSortRun run[GTK_TIM_SORT_MAX_PENDING];
|
||||
};
|
||||
|
||||
void gtk_tim_sort_init (GtkTimSort *self,
|
||||
gpointer base,
|
||||
gsize size,
|
||||
gsize element_size,
|
||||
GCompareDataFunc compare_func,
|
||||
gpointer data);
|
||||
void gtk_tim_sort_finish (GtkTimSort *self);
|
||||
|
||||
void gtk_tim_sort_get_runs (GtkTimSort *self,
|
||||
gsize runs[GTK_TIM_SORT_MAX_PENDING + 1]);
|
||||
void gtk_tim_sort_set_runs (GtkTimSort *self,
|
||||
gsize *runs);
|
||||
void gtk_tim_sort_set_max_merge_size (GtkTimSort *self,
|
||||
gsize max_merge_size);
|
||||
|
||||
gsize gtk_tim_sort_get_progress (GtkTimSort *self);
|
||||
|
||||
gboolean gtk_tim_sort_step (GtkTimSort *self,
|
||||
GtkTimSortRun *out_change);
|
||||
|
||||
void gtk_tim_sort (gpointer base,
|
||||
gsize size,
|
||||
gsize element_size,
|
||||
GCompareDataFunc compare_func,
|
||||
gpointer user_data);
|
||||
|
||||
Reference in New Issue
Block a user