Notifications
Clear all

[Closed] group faces by SetFaceColor

2010 32 bit

1 Reply
(@denist)
Joined: 1 year ago

Posts: 0

mine is 2010/64… that explains the mem difference but not the speed. :hmm:

debug/hybrid build ?

1 Reply
(@denist)
Joined: 1 year ago

Posts: 0

damn it! debug… released qsortf is faster than sort.

sorting an array of struct on a field wasn’t too tricky, but you have to move to using std::sort so you can pass the struct data index to the comparison routine


   #include  <algorithm>
   
   
   struct float_compare 
   {
   	bool operator() (Value *a, Value *b) 
   	{ 
   		return  ((Struct*)a)->member_data[index]->to_float() < ((Struct*)b)->member_data[index]->to_float();
   	}
   	int index;
   	float_compare(int i) : index(i) {}
   };
   
   //********************************************************************************************
   // usage
   // sortsf <array of structs> <#struct_member_name>
   
   Value* sortsf_cf(Value **arg_list, int count)
   {
   	Array* theArray = (Array*)arg_list[0];
   	Struct* theStruct = (Struct*)theArray->data[0];	// use the first array element as the struct template
   	Value* temp;
   
   // gets the member data index from the hash table, return undefined if not present
   
   	if((temp = theStruct->definition->get_member_value(arg_list[1])) == NULL)
   		return &undefined;
   
   // create the sorting compare object with our index
   // this is 1 based but I think max adds a dummy struct member at index 0 so it works
   
   	float_compare compare(temp->to_int()); 
   
   // sort the array
   
   	std::sort(theArray->data, theArray->data + theArray->size, compare);
   	return Integer::intern(theArray->size);
   }

the proof…

struct test 
 (
 	width,
 	height,
 	len
 )
 
 (
 	testarray = for i = 1 to 10  collect temp = test (random 0.0 10.0) (random 0.0 10.0) (random 0.0 10.0);
 	print testarray;
 	sortsf testarray #len;	
 	format "
";
 	print testarray;
 )

obviously it’s only test code but anyway enjoy

also adding


  struct test 
  (
  	width,
  	height,
  	len
  )
  
  (
  	seed 0
  	ar3 = for k=1 to 100000 collect test (random -1.0 1.0) (random -1.0 1.0) (random -1.0 1.0)
  	gc()
  	t1 = timestamp()
  	m1 = heapfree
  	sortsf ar3 #len
  	format "sortsf >> t:% m:%
" (timestamp() - t1) (m1 - heapfree)
  	format "	%
" (gethashvalue ar1 0)
  )

to the testing script gives

sort >> t:78 m:68L
  	182459010
  OK
  qsortf >> t:47 m:68L
  	182459010
  OK
  sortsf >> t:125 m:68L
  	undefined
  OK

so still pretty quick !

… and very cool!
i’ve extended your code trying to keep the style to support other ‘popular’ types:


 struct float_compare 
{
	bool operator() (Value *a, Value *b) 
	{ 
		return  ((Struct*)a)->member_data[index]->to_float() < ((Struct*)b)->member_data[index]->to_float();
	}
	int index;
	float_compare(int i) : index(i) {}
};
struct string_compare 
{
	bool operator() (Value *a, Value *b) 
	{ 
		return ::_stricmp(((Struct*)a)->member_data[index]->to_string(),((Struct*)b)->member_data[index]->to_string()) < 0; 
	}
	int index;
	string_compare(int i) : index(i) {}
};

   //***********************************************  ***************************************
   // usage
   // sortsp <array of structs> <#struct_member_name>
   
def_visible_primitive(sortsp, "sortsp");
Value* sortsp_cf(Value **arg_list, int count)
{
	Array* theArray = (Array*)arg_list[0];
	Struct* theStruct = (Struct*)theArray->data[0];	// use the first array element as the struct template
	Value* temp;

	// gets the member data index from the hash table, return undefined if not present

	if((temp = theStruct->definition->get_member_value(arg_list[1])) == NULL) return &undefined;
	
	int index = temp->to_int();
	Value* value = theStruct->member_data[index];

	// create the sorting compare object with our index
	// this is 1 based but I think max adds a dummy struct member at index 0 so it works

	if(is_float(value) || is_int(value) || is_time(value))
	{
		float_compare compare(index); 
		std::sort(theArray->data, theArray->data + theArray->size, compare);
	}
	else
	if(is_string(value) || is_name(value)) 
	{
		string_compare compare(index); 
		std::sort(theArray->data, theArray->data + theArray->size, compare);
	}
	else return &undefined;

	// sort the array

	return Integer::intern(theArray->size);
}
 

nice I added a ascending/descending flag to my original (though I don’t really have any use at the moment for it, but it’s nice to learn a bit more about what goes on under hood). We should probably start a “proper” useful mxs extension functions thread as we have deviated quite a bit from the ops original topic. !

it would be possible to make it generic as per the mxs qsort but to do that you get the mxs function call Achilles heel so keeping the specific compare calls within the sdk is the way forward.

could you start please? i have another thing to show…

Hey denis, i was actually using the sort struct routine in earnest and discovered a smallish bug in the code. If you not noticed it yet heres the fix

change


 	Array* theArray = (Array*)arg_list[0];
 

to

	Array* theArray = (Array*)arg_list[0];
 	if(theArray->size == 0)  return Integer::intern(0);
 

you need bum out early if passed an empty array, no need for nasty mxs ** system exception **

Page 5 / 5