Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How long does it take to invoke an empty function?

I have a list of items implementing an interface. For the question, let's use this example interface:

interface Person
{
  void AgeAYear();
}

There are two classes

class NormalPerson : Person
{
  int age = 0;

  void AgeAYear()
  {
    age++;
    //do some more stuff...
  }
}


class ImmortalPerson : Person
{
  void AgeAYear()
  {
    //do nothing...
  }
}

For other reasons, I need them both of the list. But for this call, when I loop through my list of Persons, I may be calling empty functions. Will this have a performance impact? If so, how much? Will the empty function, for all intents and purposes, be optimized out?


NOTE: In the real example, the ImmortalPerson has other methods that do have code - it is not just an object that does nothing.

like image 763
user664939 Avatar asked Aug 25 '11 13:08

user664939


People also ask

How do you define an empty function?

An empty function is basically creating a function without defining any operations inside it. A class named Demo contains an empty function named 'my_empty_fun' which is just completed by placing two flower brackets, without adding any functionality into it.

What does empty function return?

PHP empty() Function The empty() function checks whether a variable is empty or not. This function returns false if the variable exists and is not empty, otherwise it returns true. The following values evaluates to empty: 0.

Is Empty function in JavaScript?

The empty statement is a semicolon ( ; ) indicating that no statement will be executed, even if JavaScript syntax requires one. The opposite behavior, where you want multiple statements, but JavaScript only allows a single one, is possible using a block statement, which combines several statements into a single one.


2 Answers

Will this have a performance impact?

Highly unlikely to have a meaningful performance impact.

If so, how much?

You can quantify it exactly for your specific code paths using a profiler. We can not, because we don't know the code paths. We can guess, and tell you it almost surely doesn't matter because this is extremely unlikely to be a bottleneck in your application (are you really sitting there calling Person.AgeAYear in a tight loop?).

Only you can find out precisely by getting out a profiler and measuring.

Will the empty function, for all intents and purposes, be optimized out?

It's certainly possible but it might not; it might even change in future version of the JITter, or change from platform to platform (different platforms have different JITters). If you really want to know, compile your application, and look at the disassembled JITted code (not the IL!).

But I'll say this: this is almost surely, almost definitely not something worth worrying about or putting any time into. Unless you are calling Person.AgeAYear in a tight loop in performance critical code, it's not a bottleneck in your application. You could spend time on this, or you could spend time improving your application. Your time has an opportunity cost too.

like image 112
jason Avatar answered Oct 18 '22 20:10

jason


On a relatively modern workstation, a C# delegate or interface call takes around 2 nanoseconds. For comparison:

  • Allocating a small array: 10 nanoseconds
  • Allocating a closure: 15 nanoseconds
  • Taking an uncontested lock: 25 nanoseconds
  • Dictionary lookup (100 short string keys): 35 nanoseconds
  • DateTime.Now (system call): 750 nanoseconds
  • Database call over wired network (count on a small table): 1,000,000 nanoseconds (1 millisecond)

So unless you are optimizing a tight loop, method calls are not likely to be a bottleneck. If you are optimizing a tight loop, consider a better algorithm, such as indexing things in a Dictionary before processing them.

I tested these on a Core i7 3770 at 3.40 GHz, using LINQPad 32-bit with optimization turned on. But due to inlining, optimization, register allocation, and other compiler/JIT behavior, the timing of a method call will vary wildly depending on context. 2 nanoseconds is just a ballpark figure.

In your case, you are looping through lists. The looping overhead is likely to dominate the method call overhead, since looping internally involves lots of method calls. Performance is not likely to be an issue in your case, but if you have millions of items and/or you regularly need to update them, consider changing how you represent the data. For example, you could have a single "year" variable that you increment globally instead of incrementing everyone's "age".

like image 35
Joey Adams Avatar answered Oct 18 '22 21:10

Joey Adams