+23  A: 

Is there something faster than a loop checking that v[i]<=v[i+1] ?

No.

If this is something you wish to check often, you might want to make a wrapper class that keeps a "sorted" flag which starts out False, is set to False whenever an item is added, and add a member function sort() that sets the flag to True after sorting.

Deestan
That's a good idea ! And we already do it whenever possible :). But in this case, we're stuck with good ole vanillay std::vector...
rlerallut
Oh good ... that was what came to mind when I saw the question ... glad I appear to have thought correctly.
John at CashCommons
+5  A: 

Is there something faster than a loop checking that v[i]<=v[i+1] ?

You will need to check any value to see if it's sorted, so it won't get any faster then O(n) unless you keep track of changes yourself while mutating the vector or use a datastructure that is already sorted.

Or is it actually better to just call sort every time (though the "v is already sorted" case is quite common) ?

Remember that quicksorts worst case behavior happens when the list is already sorted (and the pivot is chosen incorrectly). To avoid such behavior you might want to check out std::stable_sort as a replacement.

Jasper Bekkers
`std::sort` is not a naive quicksort as a rule.
J.F. Sebastian
A: 

In order to check sorted you must check every item. So v[i]<=v[i+1] is the fastest possible check.

tloach
You don't need to check every item, just check until you find a non sorted element :)
crashmstr
+1  A: 

Is there something faster than a loop checking that v[i]<=v[i+1] ?

No.

However, if you are going to perform the check to decide whether to sort the vector, you might be better off just always sorting if you use the right sort-algorithm, i.e. std::stable_sort and not std::sort.

Rasmus Faber
Hmmm... For PODs, I don't believe that stable_sort brings anything compared to introsort (used by std::sort).
rlerallut
@rlerallut: the specific algorithm depends on the implementation of the library.
Jasper Bekkers
You could also do an insertion sort with a best case of O(n) when the list is already sorted. If you surpass a certain number of swaps, abandon that and just do a quicksort.
Eclipse
+6  A: 

The best way is to use

is_sorted(v.begin(), v.end())

:-) is_sorted: SGL STL reference

ShreevatsaR
That's an SGI extension. I have it with GCC but not with VC++7. True, it's only a copy-paste away ! Anyway, I'll have to benchmark its iterator-based approach to the index-based approach... Then we'll be able to say it's "the best way". :)
rlerallut
+5  A: 

Of course I have no knowledge of your problem domain, so please ignore me if what I say is not relevant, but it seems to me that if I require a collection to be always be sorted whenever I access it, a naturally unsorted collection like a vector<T> may not be the best choice.

endian
Legacy formats as well as data compacity. Besides, once the sorting is done (and it's not *that* long a part of the process), accessing a vector is wicked fast ! But I applaud your way of thinking "am I solving the right problem ?".
rlerallut
A: 

As others have noted, a predicate to determine sorted state is O(n). But from your mention of a sorted flag, I kind of wonder if you don't want something like this:

Our application's foundation libraries includes a container class which can be queried for membership. Here is a brief sketch:

class ObjList {
public:
    ObjList() {};
    ~ObjList() {};

    bool isMember(const Item *);
    void add(const Item *, bool sort = false);

private:

    unsigned int last_sorted_d;

    bool sorted_d;
    unsigned int count_d;
    Item *store_d;
};

isMember() uses a binary search on the sorted range of elements, then a linear search of items after the sorted range. Insertion can trigger a sort of the items, or not, according to the programmer's choice. For instance, if you are aware that you'll be adding thousands of items in a tight loop, don't sort until the final insertion.

The above is just a sketch, and the store is more complicated than an array of pointers, but you get the idea.

Don Wakefield
+2  A: 

If you're expecting the the list to be very close to sorted, it might be beneficial to try a modification of the insertion sort. If the list is already sorted, it just does one pass and tells you so. If the list is very nearly sorted, it will be sorted very quickly. If the list is not sorted, break out of the sort after some number of swaps and switch to a quicksort (or stable_sort).

Eclipse
+8  A: 

Consider Multiple Cpu Cores

It depends on your platform and number of items in the vector. You'd have to benchmark to find what's best.

It's not possible to answer: Is there something faster than a loop checking that v[i]<=v[i+1] ?
With: No.

Because... computers now a days have multiple cpus/cores/hyperthreading. So, it may well be a lot quicker to exploit the parallism in the computer by spliting the work of checking to a number of threads, so each cpu can be checking a small range in parallel.

It's probably best to do this via a library function rather than implementing it yourself. New versions of libraries will exploit parallism. So, if you go for a std::sort you'll probably find when you build against newer implementations of STL, they'll do the operation in parallel for you without you having to worry about it. I don't know if there are readily available versions of STL that do this already, but it's worth sticking to the library functions so that when you upgrade to a version that does, this optimization is there for you without you needing to make any changes.

Scott Langham
+1 insightful. Sadly, my is_sorted implementation (that came with a fairly old gcc version (3.4.x) is woefully basic). Besides, isn't the memory bandwidth the limiting factor for such a simple loop ?
rlerallut
It's tricky to say if the memory bandwidth would be limiting. It all depends on your platform, size of vector, size of an item in the vector, time taken for the comparison, etc. This is why timing/benchmarking is required if you want to find out how to squeeze out every ounce of juice.
Scott Langham
A: 

If when you insert items you use binary search to find the insertion point, then it's never not ordered.

Mike Dunlavey
+3  A: 
std::adjacent_find(v.begin(), v.end(), std::greater<type>()) == v.end()
newacct