使用objectsPassingTest:vs containsObject检查NSSet之间的速度差异:

时间:2016-06-30 04:50:07

标签: ios objective-c cocoa-touch search nsset

如果NSSet包含使用[containsObject:]的某个对象与使用[objectsPassingTest:block]并将stop变量设置为YES以使其在第一次匹配后停止,那么检查NSSet之间的速度是否存在差异?

此外,如果集合包含自定义类的对象,我的理解是containsObject使用isEqual:方法执行其检查,因此必须在自定义类中重写。这会减慢containsObject检查的速度,而不是NSSset包含像NSString,NSNumber等Apple类的对象吗?

我计划在有一段时间的时候运行一些基准测试,但明天会接受采访,并且希望能够为那个答案提供便利。

2 个答案:

答案 0 :(得分:0)

那么你应该运行你计划的基准测试,但你可以猜测答案。

protected void grdvMyEntries_RowUpdating(object sender, GridViewUpdateEventArgs e) { string Task = (grdvMyEntries.Rows[e.RowIndex].FindControl("ddlTasks") as DropDownList).SelectedItem.Value; string Code = (grdvMyEntries.Rows[e.RowIndex].FindControl("ddlPayrollCodes") as DropDownList).SelectedItem.Value; DateTime strDate = Convert.ToDateTime((grdvMyEntries.Rows[e.RowIndex].FindControl("txtDateEdit") as TextBox).Text.Trim()); string TimeIn = (grdvMyEntries.Rows[e.RowIndex].FindControl("txtTimeInEdit") as TextBox).Text.Trim(); string TimeOut = (grdvMyEntries.Rows[e.RowIndex].FindControl("txtTimeOutEdit") as TextBox).Text.Trim(); string ItemNo = (grdvMyEntries.Rows[e.RowIndex].FindControl("txtItemNo") as TextBox).Text.Trim(); string WO = (grdvMyEntries.Rows[e.RowIndex].FindControl("txtWO") as TextBox).Text.Trim(); string WIP = (grdvMyEntries.Rows[e.RowIndex].FindControl("txtWIP") as TextBox).Text.Trim(); string Note = (grdvMyEntries.Rows[e.RowIndex].FindControl("txtNote") as TextBox).Text.Trim(); string TimeID = grdvMyEntries.DataKeys[e.RowIndex].Value.ToString(); string strConnString = ConfigurationManager.ConnectionStrings["MAFapp"].ConnectionString; string strTmp = "Date:" + strDate + "|TimeIn:" + TimeIn + "|TimeOut:" + TimeOut + "|WIP:" + WIP + "|WO:" + WO + "|ItemNo:" + ItemNo + "|Task:" + Task + "|Code:" + Code + "|Note:" + Note + "|WHERE TimeID:" + TimeID; Debug.Print(strTmp); using (SqlConnection con = new SqlConnection(strConnString)) { string query = "UPDATE Time SET [Date]=@Date, [TimeIn]=@TimeIn, [TimeOut]=@TimeOut, [WIP]=@WIP, [WO]=@WO, [ItemNo]=@ItemNo, [Task]=@Task, [Code]=@Code, [Note]=@Note WHERE [TimeID]=@TimeID"; Debug.WriteLine(query); using (SqlCommand cmd = new SqlCommand(query)) { cmd.Connection = con; cmd.Parameters.AddWithValue("@TimeID", TimeID); cmd.Parameters.AddWithValue("@Date", strDate); cmd.Parameters.AddWithValue("@TimeIn", TimeIn); cmd.Parameters.AddWithValue("@TimeOut", TimeOut); if (String.IsNullOrWhiteSpace(WIP.Trim())) { cmd.Parameters.AddWithValue("@WIP", WIP).Value = Convert.DBNull; ; } else { cmd.Parameters.AddWithValue("@WIP", WIP); } if (String.IsNullOrWhiteSpace(WO.Trim())) { cmd.Parameters.AddWithValue("@WO", WO).Value = Convert.DBNull; ; } else { cmd.Parameters.AddWithValue("@WO", WO); } if (String.IsNullOrWhiteSpace(ItemNo.Trim())) { cmd.Parameters.AddWithValue("@ItemNo", ItemNo).Value = Convert.DBNull; ; } else { cmd.Parameters.AddWithValue("@ItemNo", ItemNo); } if (String.IsNullOrWhiteSpace(Task.Trim())) { cmd.Parameters.AddWithValue("@Task", Task).Value = Convert.DBNull; ; } else { cmd.Parameters.AddWithValue("@Task", Task); } cmd.Parameters.AddWithValue("@Code", Code); if (String.IsNullOrWhiteSpace(Note.Trim())) { cmd.Parameters.AddWithValue("@Note", Note).Value = Convert.DBNull; ; } else { cmd.Parameters.AddWithValue("@Note", Note); } con.Open(); cmd.ExecuteNonQuery(); con.Close(); tblSummary.DataBind(); grdvMyEntries.DataBind(); } } } 的实现可能会在每个成员上重复调用containsObject:;虽然isEqual:的实现可能会迭代,但在每个成员上调用块,并且块调用objectsPassingTest: ...

我认为你可以根据这个猜测。如果面试官读到SO ......那么请进行一次很好的面试。

答案 1 :(得分:0)

即使我在SO上有这种Q的问题,我也会(部分)回答它。而且我认为面试官不会得到最终结果,而是你对它的看法。

两者都使用-containsObject:进行检查。但是-objectPassingTest:可以直接执行,而-containsObject:必须调用一个块。这可能并不昂贵,但由于要执行的代码也不贵,这可能会对性能产生影响。

-objectPassingTest:旁边可以使用散列来查找对象。 NSSet中的-hash不能,因为它不知道测试是什么。该块也不能这样做,因为他逐个获取对象。

但是,如果集合中有可变对象,通常是自定义类的哪个对象,则不能进行散列,因为无法对集合中的可变对象实现有用的散列。

所以我的估计:拥有正确实现-containsObject:的{​​{1}}的不可变对象,到目前为止-objectPassingTest:将会击败select t.message_id, t.thread_id, t.body, t.date_posted from( select message_id, thread_id, body, date_posted, ( case thread_id when @curA then @curRow := @curRow + 1 else @curRow := 1 and @curA := thread_id end ) as rn from messages m, (select @curRow := 0, @curA := '') r order by thread_id, date_posted desc )t where t.rn = 1 order by t.date_posted desc; ,否则就不会那么多了。