Anonymous avatar Anonymous committed dbe26ad

One more optimization to struct bridge. Before, I was calling [[ParseSupportStruct alloc] init] in the struct metamethods which can get called a lot. These have caching already in place from a long time ago, but the alloc creates memory which needs to be immediately released if there is a cache find. This was showing up in the profiler so I made a new convenience class designated initializer which will check the cache before falling back to an alloc.

I should audit the other ParseSupport caches (especially methods) and apply the same optimization.

Also added more buttons to the blocks test. The struct performance test was placed in the block test out of laziness and should be moved somewhere better.

Comments (0)

Files changed (8)

LuaCocoa/LuaCocoa.m

 bool LuaCocoa_PushStruct(lua_State* lua_state, void* the_struct, const char* key_name)
 {
 	NSString* ns_key_name = [NSString stringWithUTF8String:key_name];
-	ParseSupportStruct* parse_support_struct = [[[ParseSupportStruct alloc] initWithKeyName:ns_key_name] autorelease];
+	
+	ParseSupportStruct* parse_support_struct = [ParseSupportStruct parseSupportStructFromKeyName:ns_key_name];
 	if(nil == parse_support_struct)
 	{
 		return false;

LuaCocoa/LuaFFISupport.m

 						// <sigh>
 						// But maybe it doesn't matter if I am just trying to get the name part?
 						//luaL_error(lua_state, "Lua type:%s not supported for variadic function parameter", lua_typename(lua_state, current_lua_stack_position));
-						//ParseSupportStruct* parse_support_struct = [[[ParseSupportStruct alloc] initWithKeyName:key_name] autorelease];
+						//ParseSupportStruct* parse_support_struct = [ParseSupportStruct parseSupportStructFromKeyName:key_name];
+
 						NSString* xml_string = [[[BridgeSupportController sharedController] masterXmlHash] objectForKey:key_name];
 						NSError* xml_error = nil;
 						NSXMLDocument* xml_document = [[[NSXMLDocument alloc] initWithXMLString:xml_string options:0 error:&xml_error] autorelease];

LuaCocoa/LuaStructBridge.m

 	int absolute_index_of_original_struct = lua_gettop(lua_state) + -2 + 1;
 	
 	// Parse support
-	ParseSupportStruct* parse_support_struct_object = [[[ParseSupportStruct alloc] initWithKeyName:key_name] autorelease];
-	
+	ParseSupportStruct* parse_support_struct_object = [ParseSupportStruct parseSupportStructFromKeyName:key_name];;
+
 //	NSLog(@"structName:%@", parse_support_struct_object.structName);
 
 /*
 {
 	
 	// Parse support
-//	ParseSupportStruct* parse_support_struct = [[[ParseSupportStruct alloc] initWithKeyName:key_name] autorelease];
 	NSString* key_name = parse_support_struct.keyName;
 	NSUInteger number_of_fields = [parse_support_struct.fieldNameArray count];
 	int stack_position_for_key = start_absolute_stack_position;
 		// TODO: Should try coercing tables as convenience
 		if(lua_istable(lua_state, stack_position_for_value))
 		{
-			ParseSupportStruct* parse_support_sub_struct = [[[ParseSupportStruct alloc] initWithKeyName:name_of_return_struct_keyname] autorelease];
+			
+			ParseSupportStruct* parse_support_sub_struct = [ParseSupportStruct parseSupportStructFromKeyName:name_of_return_struct_keyname];
 			// Need a struct to fill but can only use a blob of memory at runtime.
 			// Use VLA to keep memory on the stack
 			int8_t sub_struct_ptr[size_of_return_struct];
 #endif // LUAOBJECTBRIDGE_ENABLE_GETTER_DOT_NOTATION
 	
 	int new_start_absolute_stack_position = 2; // start after the user data
-	ParseSupportStruct* parse_support_struct = [[[ParseSupportStruct alloc] initWithKeyName:key_name] autorelease];
+	ParseSupportStruct* parse_support_struct = [ParseSupportStruct parseSupportStructFromKeyName:key_name];
 	
 	LuaStructBridge_ParseAndCopyStructValues(lua_state, the_struct, parse_support_struct, number_of_args, new_start_absolute_stack_position);
 	return 0;
 	void* struct_userdata = LuaStructBridge_GetStructPointer(lua_state, -3, NULL);
 	
 	// Parse support
-	ParseSupportStruct* parse_support_struct_object = [[[ParseSupportStruct alloc] initWithKeyName:key_name] autorelease];
+	ParseSupportStruct* parse_support_struct_object = [ParseSupportStruct parseSupportStructFromKeyName:key_name];
 	return LuaStructBridge_SetValueInStruct(lua_state, struct_userdata, parse_support_struct_object, 2, 3);
 }
 
 		return luaL_error(lua_state, "Struct name is NULL in LuaStructBridge_GenerateStructConstructorByName");
 	}
 	NSString* struct_keyname_nsstring = [NSString stringWithUTF8String:struct_keyname_cstr];
-	ParseSupportStruct* parse_support_struct = [[[ParseSupportStruct alloc] initWithKeyName:struct_keyname_nsstring] autorelease];
+	ParseSupportStruct* parse_support_struct = [ParseSupportStruct parseSupportStructFromKeyName:struct_keyname_nsstring];
 	if(nil == parse_support_struct)
 	{
 		return luaL_error(lua_state, "Struct name: %s is not in BridgeSupport database in LuaStructBridge_GenerateStructConstructorByName", struct_keyname_cstr);

LuaCocoa/ParseSupportStruct.h

 @property(retain, readonly) NSMutableArray* fieldElementArray;
 @property(assign, readonly) size_t sizeOfStruct;
 
+
+// Designated initializer. Running through the profiler, I found that creating and immediately releasing all the memory from
+// calling alloc, due to a cache find not needing the object anymore, was causing noticable overhead.
+// Use this instead to bypass unnecessary alloc call.s
++ (id) parseSupportStructFromKeyName:(NSString*)key_name;
+
+// Use the above designiated initializer instead.
 - (id) initWithKeyName:(NSString*)key_name;
 /**
   For a struct like:

LuaCocoa/ParseSupportStruct.m

 @synthesize fieldElementArray;
 @synthesize sizeOfStruct;
 
++ (id) parseSupportStructFromKeyName:(NSString*)key_name
+{
+	ParseSupportCache* parse_support_cache = [ParseSupportCache sharedCache];
+	ParseSupportStruct* check_cache = [parse_support_cache parseSupportWithStructKeyName:key_name];
+	if(nil != check_cache)
+	{
+		return check_cache;
+	}
+	return [[[ParseSupportStruct alloc] initWithKeyName:key_name] autorelease];	
+}
+
+// TODO: Now that I have a new designated initializer, I can change this to not always check parse support 
+// first since it will be redundant. However, I am unclear if I should skip adding to the cache too.
 - (id) initWithKeyName:(NSString*)key_name
 {
 	ParseSupportCache* parse_support_cache = [ParseSupportCache sharedCache];

LuaCocoa/Samples/BlocksExample/BlocksExample.lua

 
 	print(cgrect)
 end
+
+
+function OnAction12(obj_block)
+	print("OnAction12", obj_block)
+
+	local cgrect = CGRect(1,2,3,4)
+	for i=1, 1000 do
+		cgrect.size.width = cgrect.size.width+1
+	end
+	
+	print(cgrect)
+end

LuaCocoa/Samples/BlocksExample/BlocksExampleAppDelegate.m

 	}	
 }
 
+- (IBAction) action12:(id)the_sender
+{
+	NSString* error_string = [luaCocoa pcallLuaFunction:"OnAction12" withSignature:"@", the_sender];
+	if(nil != error_string)
+	{
+		[self promptUserToOpenLuaFileAtError:error_string];
+	}	
+}
+
+- (IBAction) action13:(id)the_sender
+{
+	NSString* error_string = [luaCocoa pcallLuaFunction:"OnAction13" withSignature:"@", the_sender];
+	if(nil != error_string)
+	{
+		[self promptUserToOpenLuaFileAtError:error_string];
+	}	
+}
+
+- (IBAction) action14:(id)the_sender
+{
+	NSString* error_string = [luaCocoa pcallLuaFunction:"OnAction14" withSignature:"@", the_sender];
+	if(nil != error_string)
+	{
+		[self promptUserToOpenLuaFileAtError:error_string];
+	}	
+}
+
+- (IBAction) action15:(id)the_sender
+{
+	NSString* error_string = [luaCocoa pcallLuaFunction:"OnAction15" withSignature:"@", the_sender];
+	if(nil != error_string)
+	{
+		[self promptUserToOpenLuaFileAtError:error_string];
+	}	
+}
+
+- (IBAction) action16:(id)the_sender
+{
+	NSString* error_string = [luaCocoa pcallLuaFunction:"OnAction16" withSignature:"@", the_sender];
+	if(nil != error_string)
+	{
+		[self promptUserToOpenLuaFileAtError:error_string];
+	}	
+}
+- (IBAction) action17:(id)the_sender
+{
+	NSString* error_string = [luaCocoa pcallLuaFunction:"OnAction17" withSignature:"@", the_sender];
+	if(nil != error_string)
+	{
+		[self promptUserToOpenLuaFileAtError:error_string];
+	}	
+}
+
+- (IBAction) action18:(id)the_sender
+{
+	NSString* error_string = [luaCocoa pcallLuaFunction:"OnAction18" withSignature:"@", the_sender];
+	if(nil != error_string)
+	{
+		[self promptUserToOpenLuaFileAtError:error_string];
+	}	
+}
+
+- (IBAction) action19:(id)the_sender
+{
+	NSString* error_string = [luaCocoa pcallLuaFunction:"OnAction19" withSignature:"@", the_sender];
+	if(nil != error_string)
+	{
+		[self promptUserToOpenLuaFileAtError:error_string];
+	}	
+}
+
+- (IBAction) action20:(id)the_sender
+{
+	NSString* error_string = [luaCocoa pcallLuaFunction:"OnAction20" withSignature:"@", the_sender];
+	if(nil != error_string)
+	{
+		[self promptUserToOpenLuaFileAtError:error_string];
+	}	
+}
 
 @end
 

LuaCocoa/Samples/BlocksExample/en.lproj/MainMenu.xib

 				</object>
 				<object class="IBConnectionRecord">
 					<object class="IBActionConnection" key="connection">
-						<string key="label">action4:</string>
+						<string key="label">action11:</string>
 						<reference key="source" ref="976324537"/>
-						<reference key="destination" ref="738634967"/>
-					</object>
-					<int key="connectionID">627</int>
+						<reference key="destination" ref="378020094"/>
+					</object>
+					<int key="connectionID">632</int>
 				</object>
 				<object class="IBConnectionRecord">
 					<object class="IBActionConnection" key="connection">
-						<string key="label">action11:</string>
+						<string key="label">action12:</string>
 						<reference key="source" ref="976324537"/>
-						<reference key="destination" ref="378020094"/>
-					</object>
-					<int key="connectionID">632</int>
+						<reference key="destination" ref="1018374630"/>
+					</object>
+					<int key="connectionID">633</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">action13:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="264252326"/>
+					</object>
+					<int key="connectionID">634</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">action14:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="738634967"/>
+					</object>
+					<int key="connectionID">635</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">action15:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="536660121"/>
+					</object>
+					<int key="connectionID">636</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">action16:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="552786924"/>
+					</object>
+					<int key="connectionID">637</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">action17:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="453667498"/>
+					</object>
+					<int key="connectionID">638</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">action18:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="543746048"/>
+					</object>
+					<int key="connectionID">639</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">action19:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="110336148"/>
+					</object>
+					<int key="connectionID">640</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">action20:</string>
+						<reference key="source" ref="976324537"/>
+						<reference key="destination" ref="815978765"/>
+					</object>
+					<int key="connectionID">641</int>
 				</object>
 			</array>
 			<object class="IBMutableOrderedSet" key="objectRecords">
 			<nil key="activeLocalization"/>
 			<dictionary class="NSMutableDictionary" key="localizations"/>
 			<nil key="sourceID"/>
-			<int key="maxID">632</int>
+			<int key="maxID">641</int>
 		</object>
 		<object class="IBClassDescriber" key="IBDocument.Classes">
 			<array class="NSMutableArray" key="referencedPartialClassDescriptions">
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.