So, in the last lecture we were discussing the vehicle dynamics for a rocket vehicle and we had considered the equivalent exit velocity as the prime factor in moving the vehicle. And we derived expression for the change in the vehicle velocity for three specific cases. Case one was where we have no drag and no gravity. Case two, we neglected drag, neglected drag, but the gravitational force were not 0. And case three, we considered both drag as well as gravity. We have discussed these three cases in the last lecture. Now, let us continue our discussion on the vehicle dynamics for a single stage rocket. So, let us now talk about a single stage rocket specifically. What we want to do is we want to calculate the height that is say h to which a single stage rocket will rise if we neglect drag and assume that effective velocity is constant. And now we are talking about a vertical launch. So, we will talk about vertical launch. We neglect drag and we considered that the equivalent exit velocity is constant. So, this is typically what a sounding rocket will do by the way. If you recall that I have talked about little bit of history, the first launches by ISRO were sounding rockets. Sounding rockets typically what they do is you fire the rocket. There will be a certain stage till the propellant burns. Once the entire propellant is burned, then by that time it will reach certain height and then it will continue rising further because it still has lot of kinetic energy. It will continue to rise further and when this happens, since there is no more thrust produced for the next of the duration, the kinetic energy will start decreasing. And potential energy will start increasing. A point will come when the velocity of the rocket will reach 0. After that it will start to come down. So, the maximum height reached by this vehicle h max is essentially the combination of powered flight and the ballistic flight where we have no thrust produced. So, this is what we are discussing now. So, let us consider first we are considering a vertical launch. So, we are considering a vertical flight. First let us look at the burn out condition h b. So, for the burn out we have let us say we are launching from time t equal to 0 and it reaches its maximum height like this. So, this is our launch at time t equal to 0, at time t equal to t b it reaches this height. So, this is equal to h b. So, if we consider instantaneous velocity is u, then the height is equal to u d t. Remember u is not constant. The vehicle velocity is not constant. Vehicle is accelerating. What is concerned is the exhaust velocity and we are considering there is no drag. So, now this u integral over u d t over time t equal to 0 to t b gives us the height attained by this vehicle during this flight sequence. So, now let us first look at u. What is u? For the case that we are talking about no drag considering gravity is case 2 here.  This is the expression that we have got for delta u is already integrated in time. So, now we consider at any time instant t the velocity is u. So, delta u is what is the velocity at time t minus velocity at 0. That is what our delta u is equal to minus u equivalent l n m at time t by m naught minus g here. Let us say we are talking about vertical launch from earth surface typically this rockers will not go much far. Therefore, the acceleration due to gravity can be considered that equal to the gravity at the sea level. So, therefore, this can be written as g equal to g e and theta is 90 degree. So, this is 1. So, therefore, this is equal to g e t. Sorry, theta we are talking about vertical flight. So, theta is 0. So, therefore, theta is 0 degree in this case. So, therefore, cos theta is 1 we get g e t. So, this is the expression for u and we are starting from 0 speed. So, therefore, u 0 is 0.  This is the expression for instantaneous velocity. Now, we take this and put it back into this equation. So, we can but before we do that let us consider one more thing. We have to get an expression for m also. In order to do that let us assume that the mass flow rate is constant which means that m dot is constant. So, the fuel supply is being burned at a constant rate or the propellant is being burned at a constant rate. Then if that is the case then the instantaneous mass m t is nothing but the initial mass minus the initial mass m t. m dot times t because that is the total time that it has reached. Now, m dot is constant which means that the slope is constant for the slope of mass is constant between time t and t b. So, this is if we consider this is the variation of mass. Since the fuel is being consumed at a constant rate at time t equal to 0 the mass was m naught at time t equal to t b which is here the mass is m f. Then from this triangle considering m naught to be constant we can find out the mass at any instant of time t. So, let me say this is the mass at time t. So, which is equal to m dot minus the slope of this which is m naught minus m f by t b this is the slope of this curve multiplied by the time t. So, this is the instantaneous mass. So, now what we can do is we can put it back into this equation. So, when we do that our expression will be. So, the expression for the change in velocity then will be equal to or the expression for the velocity will be equal to u equal to minus u equivalent n n here in place of m we write this.  This is the instantaneous mass whole of this divided by t b times t. 1 upon m dot. So, this is the first term in this equation minus g e times t. So, this is the expression for the instantaneous velocity. Now what we can do is this we can take m dot inside this bracket and we can write this as 1 minus m dot.   So, now what we have is let us have a look at this. Equivalent velocity is constant mass ratio is something that is fixed we know the initial mass we know the final mass. If we define m dot as constant and we know the burning time then t b is also fixed g e is also constant. So, now what we have is u as a function of time only the only variable here is time everything else has been constant everything else is constant. So, now let us take this equation and put in the expression for h b.  So, t by t b plus g e t d t. So, this is the expression which we need to integrate now. So, as we are considering equivalent is u equivalent is constant everything else is given now this is pretty simple to integrate. So, if you integrate this the final expression that we will get it before we get write the final expression let me define one more parameter. Remember in the previous expression when we obtain delta u we got delta u equal to minus u equivalent l n 1 by r 1 by m r.  So, this is something that keeps on popping up again and again. So, instead of having to work with this 1 by term we define this as a new parameter r. Now, then this expression will be represented in terms of r.  So, this is the expression for the burnt out height that we will be getting by integrating between 0 and t b. Still our work is not completed burnt out height is only up to the powered phase. Now, have to look at something beyond that after the power is completely the fuel is completely used up propellant is completely used up it will still continue to move. So, now let us see what will be the additional height it will gain in the ballistic phase. So, what we will do is let us equate kinetic energy of the mass m at m f that is the final mass of the rocket after the burnt out with the change in potential energy from the point h b to the point h b. Let me explain what I mean by that this was the powered flight we reach this lie height h b at time t b at this point all the fuel is burnt and at this point the vehicle has this height h b and it has certain velocity let us say u b.  Now, beyond this the vehicle does not have the power to maintain this kinetic energy. So, now what will happen is that the since the thrust is not present this will start to decrease and as we go up further u b decreases till it reaches a velocity 0 u equal to 0 this is the maximum height h max beyond and why is this decreasing because now only this term is acting acceleration due to gravity and this is slowing it down because it acts downward. So, now in this during this flight acceleration due to gravity will slow it down till it reaches 0 velocity after that gravity is still acting on it. So, it will start to come down therefore, this height reach is the maximum height and that can be obtained by equating the total energy here which is the sum of kinetic energy and potential energy to the total potential energy here remember the equivalent velocity we have already talked about. So, if we do that let us see now what is happening the kinetic energy at the burnout point is half m f u b square and the kinetic energy at the maximum height is 0. So, this is the total change in kinetic energy in the ballistic phase when there is no power this is equal to the change in potential energy between this point and this point and that will be now the mass of this vehicle now is only m f. So, m f times g e h max minus h b that is our total change in kinetic energy the potential energy between this two point. So, if I simplify this expression then I get the expression for maximum height. So, the h max term is equal to h b plus half u b square by g e and it is coming from this equation simplifying this equation.  This is coming from this term as you can see here equivalent t b l n r by r minus 1 is here is coming from this term. So, this is the maximum height that will be attend by the vehicle during its flight. Now, once again some of the steps I have skipped for example, the estimation of u b etcetera. So, I will give them as homework homework number 2 fill up the steps to derive this equation. So, you fill up the steps to derive this equation. So, that finally, we get this expression now this is now our expression for h max. So, we have done the mathematics we have obtained how much it will go. Now, let us look at some parametric dependence how the h max depends on the flight parameters. One thing that is important to notice here is that the height that will be reaching depends on t b the burnout time. So, burnout time is an important parameter and second part that to show here is that this term is positive u equivalent is positive. So, as t b increases h max will decrease because the effect of this term is to reduce the height. So, from this expression what we can see is that as the burnout time increases the height that will be attend by the vehicle decreases. This is something that is straight forward coming from this expression. Now, this is a important observation ideally for any operation would like to maximize the height that can be attend. So, what this expression shows that in order to get a higher height we have to have a smaller t b. In other words if you want to increase m h h max we have to decrease t b this is quite evident from this. So, hence it is required and desired to reduce the burning time as much as possible in order to meet emission requirement. However, the reason is by the way why do we say that we will be getting advantage if you burn faster because what is happening is that the higher height will be attend if we have to lift less weight because we are producing same amount of energy. If you are burning faster the rate of reduction of mass is also more. Therefore, as the burning rate increases there is a faster decrease in mass. So, the vehicle is becoming lighter in a faster way in a lighter faster and because of that it will attend a higher height. So, therefore, a short burning reduces the energy consumed in simply lifting the propellant. That is this is the reason why short burning time is preferred. However, there are some practical problems associated with very short burning time. If we consider very short burning time then what are the problems first? Burning time is how much time you are having for the power flight. You reduce the burning time you are moving faster attending the burnout height faster means we are accelerating more. So, shorter burning very short burning time means very high accelerations. So, this is very high acceleration. Acceleration is not good for the structures because acceleration in part load. So, there can be serious stresses on the structures and also the instruments. Essentially, you are increasing the G level right the perceived acceleration is the G level. So, if you are accelerating at a very high rate you are putting lot of load on the structure as well as on the instruments. First point, second point is we have discussed the drag right the variation of drag. In practical situation where we are lifting from ground we have seen that the as the velocity increases the drag will increase. Now, if we are moving in a very faster there is a massive acceleration velocity increases faster. Therefore, the increase in drag is also faster. So, there is a higher atmospheric drag acting on the vehicle. So, very high acceleration will lead to first of all high structural stresses larger load on instruments. This is the structural load I am talking about or acceleration load and higher atmospheric drag. All this essentially puts a limit to the burning rate that we can achieve because we do not want to have very high structural stresses structure may buckle and fail. We do not want to have lots of loads on the instrument because instrument will not perform the way they are supposed to if they are subjected to very high loads or acceleration. We do not want very high atmospheric drag because that will slow down the vehicle right. So, therefore, very high acceleration because of the short burning time is not something that we want to have in practical systems. This is first point second point how to we achieve the short burning time we are carrying certain amount of fuel propellant with us. If you have to burn it burn that at a shorter time you have to make it flow at a faster rate. So, shorter burning time means faster propellant flow rate right. So, therefore, a very short burning time can be mean can mean exceedingly high propellant flow rates. So, propellant flow rates now that can be limited by your hardware because first of all how much you propellant you can pump in depends on how much capacity of pumping is available with you right. So, therefore, the size and capacity of the machinery needed to provide such high flow rates may be a limiting factor. Similarly, for solid propellant rockets the burning rate depends on the chemistry or the chemical composition. So, that is for a given propellant fixed you cannot change it and for liquid as you can change it, but the point is as the liquid propellant the problem is that as we can as we go to liquid propellant higher flow rate then the amount of propellant required will increase. So, the pump and other system have to walk more they require a bigger machinery to pump at a higher flow rate which may limit the maximum flow rate that can be attained. So, because of this even though this equation shows that if you have a shorter burning time you can attain higher velocity or higher altitude by attaining higher velocity at the burn out and at the end of burn out time there is a limit of how fast can we burn. So, the typical limit typical burn out times that is attained in practical systems are between 30 to 200 seconds that is the maximum stage will be burning not more than that. Because beyond less than this 30 second if you have to burn this will be something that cannot be handled and more than 200 second will not reach enough height because the burning is so slow. Essentially what happens is that you do not have enough acceleration faster burning means higher acceleration you are reaching the exit velocity at a shorter time. So, faster burning provides us the higher acceleration which will take it further slower burning reduces the acceleration therefore, it will not go very high in the in the ballistic phase. So, what we have seen here is that typical burning time is limited between 30 and 200 seconds. One more thing that we can I want to point out here is that in the absence of drag and gravity if you are operating in the outer space then delta u will not be dependent on T b because delta u turn then is only this it does not have this term present because if gravity goes to 0 the time dependence goes off. So, it is only u equivalent l n r. So, in the outer space so this is the expression that we have obtained first for the burning velocity once again the effect of burning velocity is failed if and only if we have the drag or gravity, but if you do not have drag or gravity under some circumstances. So, when b equal to 0 and g equal to 0 this is typically in the outer space actually g is not 0, but very small. In outer space you see that delta u is independent of T b this is very important delta u is independent of T b it is independent of the burning time because of the fact that delta u under some circumstances will be equivalent l n r and in that case delta u is a function of only the mass flow rate or u equivalent. So, in the outer space delta u does not depend on the burning time. Now, if you have a vehicle moving at a very high speed in outer space we need a very small acceleration just to maintain the speed or increase it little bit that is why electric propulsion systems are useful there because we can just small amount of energy can be used and that will give the increase. So, we can give that small amount over a period of time we do not have to give it together a small amount of increase in the period of time and slowly it can built up and go to the very high velocity. That typically is a maneuver to change from one orbit to another orbit it takes about 24 hours you have that window to move it from one orbit to another orbit they were prolonged period of time you can do it slowly by providing small amount of thrust and getting from one altitude to another altitude because you do not have the dependence on T b and that is possible only in the outer space because it depends only on this factor nothing else. So, this is a very important observation for rockets. Now, with this we come to an end of our discussion on the vehicle dynamics for single stage rockets, but some more parameters I like to define at this stage which will be useful in the next topic where we take the multi stage rockets and after that what we will do is we will look at the practical performance of single stage rockets how the practically the performance depends on various operating parameters. So, here we have defined the mass ratio we have defined the inverse mass ratio let us define some other parameters as well. So, the total mass of rocket let us say m dot essentially is sum of various components a rocket will consist of the payload. So, first of all the payload is the most crucial and critical thing all our effort is actually to deliver the payload to certain location. So, the most important mass is the payload mass. So, first of all let us talk about the payload mass let us define it as m l most important mass other. Now, in order to put this payload we have to provide certain acceleration certain velocity and that can be achieved with burning the propellant only. Therefore, the next important mass is the propellant mass. So, next is propellant mass. So, let us write it as m p and now the payload and the propellant all of them have to be put together they have to move together. So, you need an external structure to carry all of them then the third important thing is the structural mass and furthermore this structure has to withstand all the external forces that is going through all the loads that are acting the structure has to withstand. So, that is also a very important factor. Now, we can have further slug classes of structural mass, but let us just focus on this three because payload is something that we want to deliver propellant something we use up. So, what we say is everything else let us say is the structural mass. So, then every other mass we put it under this category of structural mass which will include the everything other than payload and propellant that is it will include the casing it will include the motor it will include the pump it will include the instruments everything is part of the structural mass. So, therefore, the total initial mass now is the sum of all this.  So, total initial mass of the rocket is the sum of the payload mass propellant mass and structural mass and now after the flight is over other sorry not after the flight is over after the propellant is burned out the final mass is what remains after the propellant is burnt out is this is gone only this and this.  So, this is equal to then the payload mass and the structural mass. So, our final mass is the sum of the payload mass and the structural mass and every all the propellant has been used up.  We can define this mass ratio like this or we can also change it little bit we have defined r we have said that r is inverse of m r. So, r is equal to m dot by m f.    We can write r like this. Now, we define a new parameter which is called payload ratio.  So, very important parameter let us say we express it as lambda. Play load ratio is defined as the payload mass divided by the initial mass minus the payload which is all the mass except the payload mass. So, this is the fraction.   So, the payload ratio is the ratio of payload mass to the ratio of the sum of structural and propellant mass. This is something is a very important parameter and typically would like to have large payload ratios because we would like to put up as much payloads as possible with as little expenditure of propellant or structural weight as possible. Therefore, this is something we want to maximize. We want to get as much payload ratio as possible for economical operation. So, we have defined the payload ratio. Next let us define one more parameter which is called structural coefficient. Payload ratio is a measure of how efficiently the payload is delivered. Structural coefficient on the other hand is the estimation of the structural efficiency. So, structural coefficient is represented by the term epsilon which is defined as again the structural mass divided by everything else but the payload.  So, here both in these definitions the denominator is m p plus m s that is the propellant mass and the structural mass. So, this now can be written as if I look at the definition of the final mass m f. We have seen that m f is equal to m l plus m s.   So, this can be written as overall mass minus the payload mass. So, the structural coefficient is defined like this. Structural coefficient is the measure of vehicle designer skill in designing a very light tank and support structure. How efficiently you can make it and also it depends on the choice of material for making the system. Typically if you are using metals it will be heavier. Nowadays people use composites which are much lightweight and can withstand higher load with that the structural coefficient has been reduced substantially. Structural coefficient is something you do not want to have very high value. You want to have small value of structural coefficient payload ratio you want to have very high value. So, these are the two parameters which are very important as we will see as we go along.   Here if I add 1 it becomes m s plus m p plus m s sorry no.   Now, if I do 1 plus lambda upon 1 lambda plus epsilon then this is equal to this divided by this.   Therefore, this is equal to r. So, what we have proved is that r is equal to 1 plus lambda upon lambda plus epsilon. Keep this definition in mind when we go to multistage rockets we will be using this very extensively and these expressions are also used for optimizing the rockets. So, with this we come to an end of this discussion. Next time we will talk about the actual performance of single stage rockets. We will discuss some performance parameters how they vary with certain operating conditions and after that we go to multistage rockets. Thank you.


Assalamualaikum warahmatullahi wabarakatuhu, Bismillahi r-Rahmani r-Rahim, Alhamdulillahi wassalatu wassalamu ala Rasulillahi wa ala alihi wa ashabihi ajma'in. We commence in the name of Allah subhanahu wa ta'ala, most gracious, most merciful. We send blessings and salutations upon Muhammad sallallahu alaihi wasallam, his household, his companions. We ask Allah subhanahu wa ta'ala to bless them all and to bless every one of us to accept from us the fasting and the prayer that we are engaging in in the evenings and the change in lifestyle for the better that we have done during the month of Ramadhan. May Allah subhanahu wa ta'ala keep it a permanent change. Ameen. My brothers and sisters, you know when you see a scholar of Islam, when you see an Imam of a Masjid, when you see a person teaching Hifb, when you see someone teaching the Arabic language, the Quran and the hadith, you would not expect him to be driving the latest S class Masjidis, am I right? You would not expect him to be having the best house in Rilands, nor would you expect him to be a millionaire. Unfortunately we have a sickness and this sickness runs down from centuries. We believe that those who are religious or those who are teaching the religious are not supposed to be paid beyond 50,000 rands a month. Is that right? Everyone is quiet, you're shocked. If it was the case we would cut our jobs and become sheikhs, right? What we believe is, and unfortunately it's a reality, I'm talking about reality with due respect to everybody, sometimes that a person teaching Hifb is supposed to get the minimum wage or a little bit more than that. Their children are supposed to be going to public schools or they are supposed to be driving a Camry, I don't know if that is still the case. They are supposed to be people who perhaps should not have lots of money, they should not be wearing a Rolex, nor should they be having a Mont Blanc, nor should they be having anything that is expensive. It's a sickness. If they do, what's he doing, man? He must be stealing, he must be doing this. He must be pinching, he must be pushing drugs and so on. This is the reality. People believe from a long time that, you know what? If you want to teach religion, you've got to be a pauper. As a result, we have no respect for those who teach our children the Qur'an. Yet, خيركم من تعلم القرآن وعلمه. The best from amongst you are those who teach the Qur'an and who learn it and teach it, the best. So better than your doctors, your accountants, your rocket scientists, the Hadith says, the best. Those who learn the word of Allah, Subhanahu Wa Ta'ala, and teach it. How ironic, Subhanallah, Subhanallah. I told you all due respect to those of other fields. We tend to consider the statement that ulama make as something low, because for us, they are worth being handed out little handouts to. May Allah Subhanahu Wa Ta'ala forgive us. The day that changes and the day the salary of the ulama is at par with the doctors and the professionals and those who are Ph.D. holders, etc. That's the day we would have some respect for the scholars of the Deen. When they talk, we would listen. When they say, we would go to hear what they have to say and we would take serious what they are teaching. May Allah Subhanahu Wa Ta'ala grant us a deep understanding. Many children, they look up to people, I want to be like this uncle. Do you know why they do it? Today, we are living in a materialistic world. Let's not fool ourselves. The children do it because they see us admiring the vehicle of this person, the clothing, perhaps the perfume, perhaps the phone, perhaps everything else, perhaps the house, not realizing that in a lot of cases, it's still being paid. The mortgage is still being paid and the person really owns nothing. It's just a show. But the children want to be like that because we've trained them subconsciously sometimes that you know what? That is the life, that is success. Such that Subhanallah, when someone proposes to marry our child, we take a look at monetary living and the level of finance before we look at the Deen and the religion. It has happened. It's already happening in society. Now, why do I start this way? I start this way because we were speaking about some of the points of confusion that the kufar of Makkah tried to create regarding Rasulullah sallallahu alaihi wa sallam to try and divert the rich people and the wealthy and the powerful of Makkah from listening to what he had to say. So they started creating confusions. If you look at Surah al-Furqan, which is Surah number 25 of the Quran, verse number 7, Allah subhanahu wa ta'ala makes mention of one of these issues they tried to create. Like I told you, it's come down the generations. And they said, They said, What is it with this man who claims to be a messenger? Yet he is walking in the marketplaces and he eats food just like everyone else. What's wrong? He's supposed to be different, just like what we say. He's supposed to be different. How can he go into the marketplace? He's supposed to be sitting and teaching the kids. How can he have a deal that is bigger than our deal? How come he got the million and we only got a hundred thousand? This is what happens. And it happened from then. They picked or they tried to pick on Rasulullah sallallahu alaihi wa sallam saying, How could he eat food? Why? Imagine you enter a restaurant and the rich and famous come and purchase food worth a thousand rands. And here comes the sheikh from down the road in the masjid and he purchase worth five thousand rands. They look at him and he literally, as they notice what he's done, subhanallah, more generous, he's got more money and so on. They wouldn't feel right because some balance has gone amiss in our society if that was the case. Okay? It's a fact. I know some people might feel hurt. It's not to make people feel hurt. It's to make us think, I'm sure my colleagues would be proud of what I said today because they face a challenge even for the school fees of their own children. Their children are not supposed to go to the private schools and colleges. Why? Because your father is an imam. That's it. It's a fact. We feel somehow that these people are not entitled at all to anything to do with this world. You know what? They're human. They also need a phone. They also need cars. They also need houses. They also have family members. They have children, subhanallah. Sometimes their children excel in worldly living such that they go way beyond the wealthiest of society. And the father was just an imam. I know examples of that. May Allah subhanahu wa ta'ala grant us a deep understanding. So they said, what is it with this man? He actually eats food like what we all do. And how could he be eating food? If he was really a messenger, he should have an angel with him who looks after his affairs. An angel. You know, you should be sitting in the masjid. The angel does everything. You know what? The ulama also need to interact in the marketplace. They also need to buy and sell. They also need to, sometimes, they also need to go to the doctor. They also need to meet their needs. Their families also want to go on a holiday. It doesn't mean that because they are scholars of the deen, that their families can forget about going out on a holiday or about even going out to eat. May Allah subhanahu wa ta'ala safeguard us. So in the case of Muhammad sallallahu alaihi wa sallam, they were trying to tell the people of Makkah that this man is not a messenger because he is just like us. Yet he was not like them. He was a messenger of Allah, subhanahu wa ta'ala. So they said, why didn't Allah subhanahu wa ta'ala send an angel to be warning together with him, all the people, hey, I'm an angel, this is a messenger. It's not going to come your way. You cannot decide when you have the examination paper at your final exams. Why didn't the teacher write the answer at the back of the paper? That was the examination. The answer was given to you prior to the test, not during the test. So we have the answer from Allah, subhanahu wa ta'ala. We cannot choose and decide what Allah should have and shouldn't have done. The test was decided by Allah, subhanahu wa ta'ala. So the second thing they said is, if Allah willed, he should have kept for him a huge treasure or he should have had a separate garden from all hours from which he could eat and consume the best of food. When we saw that, we would then be able to follow. Now remember, these are all excuses. What shaitan does, when shaitan does not want you to listen to something correct, he makes you find fault in the person so that you can ignore the message. And this is why I always say the difference between the prophet of Allah, subhanahu wa ta'ala and the ulama is that the prophet was infallible. He was pure, he was perfect. But the ulama, there is a human factor in them that makes them earn. They may do things that may not be correct. They may even make mistakes. They would probably even commit sin to a certain extent and community never forgives this. Community looks at them as though you are supposed to be a prophet of Allah. For you to make a mistake, no way, it cannot be. Yes, I do agree. There are levels of errors, levels of mistakes. Beyond a certain point, one might want to take look at that issue and resolve it in a more serious matter. But my brothers, my sisters, you will find a few discrepancies.  He has arrived two minutes late for the Salah. Salah was supposed to commence at 5.45 and he was here at 5.47. I promise you, that is the test of those who are behind him. I recall once in Johannesburg this happened and the Imam, may Allah grant him Jannatul Firdaus, he's passed away. He told me two minutes, I was late. And when I got up, the people started, I could hear voices at the back. You know, the people all want to make a noise late, late. He said, I have led you in Salah for so many years. Today, I was slightly late. Imagine the punctuality. So many years I've led you in Salah. One day I'm late and look at what you are doing. Whereas from among you, every day they are late comers. You turn around, there will be rows of people who stand up, especially when it comes to Salatul Fajr. May Allah, Subhanahu Wa Ta'ala, help us, protect us from these type of standards that are double standards. So once in a while, we need to overlook. Yes, if it happens on a regular basis, you may want to deal with it differently. Gently remind, you know Imam, Mashallah, and this is if you're in authority and you say it in a very humble way, very polite way, treating the Imam like a VIP, because that's what he is. Allah says he's doing the best possible job. And here we are mowing over them, as though they are just mere lawn. May Allah, Subhanahu Wa Ta'ala, grant us an understanding. So Allah, Subhanahu Wa Ta'ala says to Muhammad, Salallahu Alaihi Salam, Take a look at how they have made examples, what type of examples and what they are saying about you. They are indeed going to stray as a result. And then Allah, Subhanahu Wa Ta'ala says, As a result of that, because of that, they will not be able to find that path. Like I said yesterday, when you look at the messenger, Salallahu Alaihi Salam, with the eyes of sincerity, you will be guided.  Subhanallah. So the same applies to the message of the Deen. Look at it with an open heart, look at it with a beautiful eye, and you will find the guidance. You will realize what that message holds in value for you. May Allah, Subhanahu Wa Ta'ala, make it easy for us. Listen to what Allah says to Muhammad, Salallahu Alaihi Salam. The best of creation, the most noble of all prophets of Allah, Subhanahu Wa Ta'ala. Allah says to him, Glory be to Allah. All praise is due to Allah, Subhanahu Wa Ta'ala. If Allah willed, He could have given you even better than what they say you should be having. He could have given you gardens, plush gardens with everything. Allah says if Allah wanted, He could have given it to you. So why didn't Allah give it to him? For many reasons, one of them is, what is the test if there is evidence in front of you to prove something and we claim, I believe. What do you believe?  If I were to tell you how many fingers is this, and you say two, you saw the fingers. But if I told you, for example, two days later, how many fingers did I put up? Those who say two will have to be believed by those who didn't see it, right? And those who believe, the ones who have seen it, are indeed from among those who trust them. They trust them. Otherwise, you wouldn't believe them. So the point I want to raise is, if Muhammad SAW had an angel with him, telling everyone, hey, this is a messenger, what was the point of testing the belief? It was in front of them. But Allah says, hang on, we're going to send him. We're going to send him with the signs. We want you to use your brain, and we want you to believe. And belief will entail an aspect of the unseen. Believe him. When he tells you that this is what Allah said, see, do you find it in your heart to believe that? If you do, you are true. If you don't, what was the point of claiming that I bear witness, Muhammad SAW is the messenger? When whatever he has said, we're not even prepared to believe it. May Allah SWT forgive us. I hope we've understood this point. The point being raised is connected to belief in that which Muhammad SAW brought with the evidence that is enough already. We don't need to ask for a supply of greater evidence. May Allah SWT grant us a deep understanding and grant us correctness of Iman and Yaqeen, faith and conviction. Amin. So verse number 11 of Surat Al-Furqan speaks about another very interesting aspect. We need to save ourselves, my brothers and sisters, from the fire. We are believers, aren't we? We believe there is heaven and hell. We believe that we would like heaven and we would like to stay away from hellfire. So that is why Allah gives us prohibitions and he has laid down that which is obligatory, both of those. He wants you to do things. He wants you to abstain from things. And in the middle, he has kept what is known as repentance so that you can always come back and you can always have hope in this paradise that he has prepared and have hope in being saved from hellfire. But there are some who don't believe. They don't believe. So the people at the time of Rasulullah SAW, a lot of them used to say, We have nothing besides this life. Where we are just living, we will die and we are alive. Which means I'm living now. I make the most of what I can for now.  When I die, there is nothing remaining. It's over. Let me enjoy as much as I can right now. I'm sure you know the statement YOLO. Or you only live once. The idea behind it is just do everything. Do whatever you want. Well, if you believe that there is a hereafter, you believe that you don't only live once. You live more than once. Once now and later on, there is another life, life after death. And if you believe in that, you prepare during this time for that particular time. Now, if someone did not believe at all, why should he be irritated when others believe? I give you an example. The Prophet, Sallallahu Alaihi Wasallam, recited the verses connected to the Akhira and connected to Hellfire and the burning in Hellfire and the punishment of Hellfire. So Allah says, Indeed, they have belied the hour. They don't believe in the hour. They don't believe that there is a last day. We have prepared a burning blaze for those who don't believe in the hereafter. Pause there. They got upset. They got angry. Why would they get angry when they don't believe in the hereafter? This is the irony. So a person says, I believe there is nothing to come after death. Well then, no matter what I believe, why does it hurt you? Why are you so worried? Why is it when we talk of heaven and hell? Do you get excited? You don't even believe that after death there is anything. So if you are worried about it, it means deep down you actually do believe. Subhanallah. You get the point? And this is why once I was sitting with an atheist and he was so angry and upset about our belief in the hereafter and I told him exactly this, that you should be the last person talking. You don't even believe that there is anything coming after this. You don't believe. So why are you so worried? He says, but it's nasty. You know, you're blackmailing the people and I said, that's not true. Nobody is blackmailing anyone. For those who believe, this is what they believe. Those who don't believe, don't believe. That's it.  Subhanallah. May Allah subhanahu wa ta'ala grant us understanding. So the point I want to raise is when someone gets upset about the hereafter and what is prepared for those who believe, in essence, deep down, they actually do believe that there is a life after death. That's why they are so worried. May Allah subhanahu wa ta'ala help us. So to save ourselves, we know that yes, there is hellfire. We will do good deeds so that inshallah we can be saved from hellfire and we will seek the forgiveness of Allah subhanahu wa ta'ala because we are human beings. Now every time that Allah subhanahu wa ta'ala speaks about the burning blaze of hellfire or he speaks about the punishment that he has prepared for those who transgress immediately before or after he speaks about paradise, the goodness, the forgiveness, the beauty that has been prepared for those who repent, for those who believe. So this is why immediately after that Allah asks a question. Verse number 15, Surat al-Furqan. Qul. Qul meaning say, Muhammad sallallahu alaihi wa sallam to them. Is that burning blaze better or is heaven, jannah, the gardens of paradise better that have been promised to the muttakun? The muttakuna, those who are conscious of their maker. If you're conscious of your maker, you become a muttaki.  So that is why taqwa is translated as piety. A person who fears the punishment of Allah. A person who loves Allah enough to stay away from haram. And a person who loves Allah enough to fulfill whatever Allah has asked him or her to fulfill. That is a muttaki.  As soon as your eyes close, in fact just before your eyes close, you would be from among those who's given glad tidings by the angels of a good place and a good abode that you are going to go to. Amazing. So this is Allah subhanahu wa ta'ala. You know what he says. And I need to spend a long time on this. Verse number 16 of Surat al-Furqan. Those who have entered paradise for them in it shall be whatever they desire. And Allah says in the next verse, this is a promise that you can hold against Allah subhanahu wa ta'ala. You can hold him.  Allah says, it is a promise that is questionable. Meaning you can question the person. In this case, the deity, Allah himself is promising. If I say, that means I'm responsible. So Allah is responsible to give you anything you wish. Now pause there for a moment. This should solve our problem. What problem? Many people ask, what am I going to get in heaven?  What do the women get? Relax. Whatever you want, you're going to get it. Trust me. Anything you want. Now, we start saying, okay, that means my cat is going to be with me. That means the dog is going to be with me because I want that. That means, not this guy here, but the guy down the road, I want to be with him in paradise. And that means that, you know, I need to have this car. What's the latest vehicle? Can someone say one of the latest cars that they are today? Can anyone make mention of one? Okay, Lexus 2018. Okay, that's a clever one. Say S-Class, BM, whatever, 2018 model. My brothers, that is such a cheap Dua. So cheap. Can I explain why? Bring in the Bugattis and the Lamborghinis and the Ferraris. Trust me. In one or two years, they'll be outdated, outdated. Imagine the people who died in 1930. Oh Allah, I'd love to have this Mercedes. That has come out. The latest model. Ya Allah, I'm going to work hard when I get to Jannah. I need it. Relax. Those 1931 Mercedes, no one wants to see them today. Besides those who deal in vintages if the car is of a good condition. No one wants it. So it's a wrong Dua. The Dua is actually way beyond that. If Allah says, I'll make you happy, it means with whatever is there completely in front of you way beyond what your imagination can think of. This is why the Hadith describes this. You see, people get upset. I've heard women say, you know men are promised so much. We're not even promised much. I'm not even bothered. I'm not interested. And now I don't want to read my Salah anymore. I've actually heard statements of that nature. May Allah safeguard us. It's a pity because they don't realize this verse. And I've just mentioned it. Verse number 16. Go and read it of Surah Tulfurqan. Allah says, He promises whatever you wish for. That's what you will have in Jannatul Firdaus. So what you got to do is only one thing. Make sure you get there. That's it. There's nothing else you need to worry about. Once you are there, trust me, everything will fall in place. You may never think of your cat because there might be something else way beyond those kittens. Subhanallah. You may never think of the cars that were in the world because Subhanallah, there is something way beyond in terms of mode of transport. If any, I don't know. We can only say what Muhammad SAW said. In paradise is that which no ear has ever heard about. No eye has ever seen. Way beyond whatever your eyes have seen. What have you seen? The most beautiful of men or women depending on whether you're a male or female. Jannah is way beyond.  You'll say, Oh Allah. Oh Allah. And he is the dawn. Subhanallah. And you're just looking. Subhanallah. This is why we say, the idea is to get there. Forget about Shaytan's plot is to make us fight about what we're going to get in a place that we actually have not even reserved a seat in. That's the thing. You're planning your holiday to Hawaii but you don't even have an airline ticket, imagine. First, work hard to get the ticket. Then we'll talk about what we're going to do when we get there, inshallah. So the same applies. Work hard to get your booking. When you get into Jannah to Firdaus, you will see everything. Whatever you wish for shall be in paradise. And Allah SWT says that you can actually ask for this. And I'm telling you, you can ask for it. Kana ala rabbika wa'dan Mas'oola. Allahu Akbar. May Allah SWT bless us all with Jannah to Firdaus. And may Allah SWT make it easy for us to work towards there. And trust me, we will be the happiest. The last part of that hadith says wala khatara ala qalbi bashar. What is in paradise has never even crossed the heart or the mind of a human being. So it's way beyond whatever has crossed your mind. Recently, I came across, you know, these little drones that they use to take photographs. Then they used to strap, or they strap the medication on it and they send it to your house within a five kilometer radius sometimes further. Now they have these drones that can carry 200 kilos. So you stand on it and it takes you up. Where do you go? I fly in the air to where I want to go. And I've got a little joystick in my hand and this is a reality. It's being used now on earth, in this world. And at the same time, they are trying to commercialize it to make it available for the public as a mode of transport. So the next time you come to this masjid, perhaps for Taraweeh, a few of us might be having our little whatever they call, I don't even know what they call these, they hover flies or something of that nature. And you would have a few of them parked there outside. And I hope those are the imams of the masjid that will come with those. Masha'Allah Tabarak Allah. I think we've got the message. May Allah SWT bless us all. May Allah SWT grant us goodness. I want to end by making mention of a verse where Allah SWT speaks about the test, the test that I spoke about earlier. Those who don't believe, those who don't believe, they come up with weird excuses. Listen to what Allah SWT says, verse number 21 of this beautiful Surah, Surah Al-Furqan. وَقَالَ الَّذِينَ لَا يَرْجُونَ لِقَاءَنَا لَوْلَاُنْزِلَ عَلَيْنَا المَلَائِكَةُ أَوْنَرَا رَبَّنَا Those who are not looking forward to meeting with us, speaking here about the year after, those who are not looking forward to meeting with us, what do they say? They say, don't the angels come down to us to prove a point? Or why can't we see our Rabb? And then we will believe. Well, once you see him, what's the point of saying, I believe, you've seen it. Belief in the unseen is what we are being tested about. So if you cannot believe in the unseen, how can you call yourself a believer? I believe because I know whatever Muhammad SAW has come with, I'm convinced that it's absolute truth. I'm convinced that the Quran is flawless. I'm convinced that the message of the Quran is amazing. It promotes the highest level of peace and the highest level of understanding and living Subhanallah. So Allah says, those they don't even believe in the year after, look at what they're saying. They're saying, okay, show me Allah, then I'll believe. Okay, bring the angels, then I'll believe. And in another verse, Allah says, even if the angels came, even if they saw Allah, they would still not believe. May Allah Subhanahu Wa Ta'ala not make our hearts hard. Whenever the truth comes to us, may we be from among those who believe, may we be from among those who turn for the sake of Allah.  Signs to turn to Him, to get closer to Him. We are getting older as the days pass. We're not getting any younger. It is definitely about time that we saved ourselves from the wrath of Allah Subhanahu Wa Ta'ala by becoming better people for His sake, quitting our bad ways, increasing the good, and thereafter achieving the pleasure of Allah Subhanahu Wa Ta'ala. I'll say this, may Allah's peace and blessings be upon us. Subhanallah, and praise be to Allah. And praise be to Allah. We bear witness that there is no god but Allah.


So hi to everybody. So this is the London Closure and Meetup. Today, we have the pleasure to have Justin with us. Justin has been developing in Closure for over 10 years and he's passionate about microbenchmark, about JIT compiler and dynamic languages. He's been working on JMH for Closure, a library developed by the JDK JMH library, which is the microbenchmark harness. And he's gonna tell us more about why this is a good choice for microbenchmarking. I don't know if you guys have any experience with microbenchmarking. For me, it's like a terribly frustrating that when you run a benchmark and without any change, you repeat the same benchmark you get completely different results. So there is actually a paper on, from Mikosky, I think, 2009. And that shows that there is up to 40% of layout biases just for the memory layout. And this is now a long L1 cache and L2 cache that can influence your performance benchmark. And plus, there is on top of that all the statistical error that you can do. There is also another researcher called Emery Berger that ran the little nice presentation on Strange Loop that shows that even the Linux username can influence your performance benchmark. So they were running the same binary on the same machine with the same test, the same configuration, same setting seven, just two different username and they were seeing different performances. So they actually built also a tool for the C++ compiler to amortize this problem. So the JMH is doing quite a lot of internal things and statistical measure to avoid all these things. And Justin will tell us a lot about how it works and how to use it, how to get the best out of the library. So I will now pass it to Justin so they can start his presentation. We're gonna have the presentation at the end. Justin is gonna take some more questions. So please collect your questions so that we can at the end have a discussion as well. So Justin, you can start sharing your screen as well. Okay, hi, my name is Justin and I'm here to talk to you today about my library for benchmarking on the JVM enclosure. First off, I do wanna say thank you again to Bruno for inviting me. This is my first time giving any talk, giving a talk of any kind, but I've been a language and performance enthusiast for many years. Thanks for having me and I'm happy to be here. So a couple of things to get out of the way upfront. This talk is not gonna be about teaching you how to write fast code. This library is a great tool to have available if you wish to do so, however. Second, benchmarking and performance tuning is one of the more complicated topics on the JVM and since I have no way of knowing the general level of experience of the audience here, I'm going to be assuming just a casual familiarity with the subject. And third, to save some syllables, I'm gonna be using the terms benchmark and test interchangeably, so don't be confused. So this is a little bit about me and how I kind of got to this point. A few years ago, I was writing a compiler enclosure. It would take data that basically described the superset of regular expressions and construct optimized parsing code. For the compiler, I was using another library that I wrote for functional bytecode composition. So at one point, I had multiple different buffer implementations. For example, there was one that used raw byte arrays and there was one that was using a custom immutable type that I wrote and so on. And I was benchmarking them against each other for different workloads. This is how I usually work when I'm benchmarking by testing different implementations and algorithms against each other. As I expected, the byte array version generally was the fastest, but I just wanted to know by how much I was going to be picking just one implementation in the end to use. Inexplicably, however, sometimes an implementation would just slow down by a significant amount, seemingly at random. And I was doing the testing via criterion. I'm sure most of you have heard of this library. It's a great, well-written library. That's the go-to library for most people when benchmarking closure code. And I want to say upfront that this talk is not about batching criterion or any other library. But in my case, I would benchmark the parser with the different implementations and I started to notice that the results would come out different depending on what order I ran them, how many times I ran them and so forth. When nothing else had changed in the code, kind of like what Bruno was talking about before. Whether in a REPL or from a script, the results would very rarely be as consistent as I expected. So I examined everything I could think of at the time. I checked for configuration issues, profile, and this was on a dedicated box with nothing else really running on it. So this got quite maddening until I finally realized I could get better consistency if I ran each individual test separately in a new JVM process each time. The timings still weren't as stable as I would have liked, but at least it was something. I knew basically how much faster certain implementations were relative to each other and better than that, I never saw the random slowdowns. So at that point, I decided to learn more about benchmarking on the JVM. So this kind of thing wouldn't come back to bite me again in the future. But I also started to wonder what alternatives might be available to the existing libraries that I had been using. This is a quote from a talk given in 2018 by Gil Tenne, a person that I think many would agree is one of the foremost experts on JVMs. To my knowledge, it seems the general consensus is that if you're doing serious benchmarking or micro-benchmarking on the JVM, JMH, the Java micro-benchmark harness is a tool you should consider using. JMH closure is a functional data-oriented interface to JMH. I hope in this talk to give you some reasons why someone like Gil Tenne would recommend it. I'm going to touch on why these results a little bit were the way they were a bit later. But for now, I'm going to look at a benchmark I created for this talk. I focused on making this as easily digestible as possible. It's not meant to be a realistic example. It's for demonstration purposes. It's meant to shed some light on a larger issue here. The results were taken from multiple runs of the entire benchmark suite using the latest versions of each library. I'm showing only a sampling of the runs here. This sample is representative of the whole, however. I'll be creating a GitHub repository for this talk that will have all the code, data, and materials for this and all the subsequent examples. They're all runnable code, so feel free to try them yourself if you want to compare with my results, which is always a good idea. Anyway, this took many hours on my hardware, which is why none of the benchmarks in this talk are going to be run real time due to constraints and not wanting to overload my Amiga machine when I'm streaming here. Benchmarking correctly on the JVM takes time. Okay. We have a simple protocol. It essentially just does what closures and function does, except that it's extensible. It should be pretty self-explanatory. I'm not, if you're not familiar with the index interface, classes like persistent vector implement it to provide access by index. You can see at the bottom some basic examples. Pretty simple. Now, we're going to run some tests using inputs of different types and sizes. First, we'll be using criterion. This is an excerpt of the runner script. I'm not going to show the entire code that generates these results for this first example. Again, this will be in the talk repository. We're simply going to create a vector or a string of a given size that access a value by index in the middle. I should say two, if you've never done serious benchmarking on the JVM before, note that both libraries will both run for a warm-up period to get the optimizer to kick in before doing the measurements. Okay. Here's some results. These are measured in average time, lower being better. We see here, even when extending existing types like char sequence, protocols are pretty quick. Under the hood, protocols use what's known as a polymorphic inline cache and is a simple optimization when invoked. If the current type matches the most recently seen cache entry, it avoids the overhead of a table lookup and this fast path is going to amount to just a couple of comparisons. Anyway, we'll get back to these results in a second. In JMH closure, we usually write our benchmark specifications as data, not as code. There are benefits to doing this, but for now you're going to have to take my word for it. So don't worry about the format of this just yet. Real quick, you will notice that the functions to be tested are given as namespace symbols and their argument names correlate with the state's key below and so on. I'll explain all this in detail in just a little bit. Okay. So now the excerpt of the code that uses this data. Importantly here, we're not passing a function object in memory to be benchmark like with Craterion. We are providing the data from our file along with some options. I'll explain why this is later. The options I'm not showing here are just configured JMH to report results in a comparable format. And for anyone who is familiar with JMH, note that I have configured it to be as fair as possible to Craterion. So again, some results. We're not going to dwell on these exact numbers for the time being. I'll get back to them in a second, but right away we can see Craterion is telling us that string access is slightly faster than vector access while JMH is telling us for small vectors, they're basically identical. Okay. The one thing we might be able to derive from this so far is that once a closure vector gets to a certain size, here 100,000 elements, it no longer maintains constant time complexity comparable to a string due to it being a tree or a tri depending on how you want to pronounce it, which is expected. Before I continue, keep in mind, I'm not showing all the data points in these examples. This is just the primary result to keep it simple. I have preserved the whole dataset, however, so things like standard deviation and percentiles, et cetera are available. So what happens if we interleave the implementations? So before we had string, string vector vector, now we're doing string vector, string vector. So with Craterion again, here the first table is the previous result. Notice the arrow here on the second string row. For the interleave result, we see something interesting and this is a trend across all 10 runs. The second string test here in the second table is slower than the first and is now around as slow as indexing the vector. Notice the arrow next to the row again. Now this is actually somewhat misleading. If we instead interleave with the vector test first, like vector string, vector string, displayed here in the third table, we see that the vector result is now faster than the previous and the string measurements that follow it. I can talk a bit more later about why this is happening, if anyone is curious, but I'm fairly certain that closures protocols are not at fault for the slowdown here. Anyway, the actual numbers are not really what is important here. I have a relatively ancient machine here. Results on newer machines will be faster, et cetera. All I'm trying to show is inconsistency with the previous results. And, oh no. So now with JMH. Again, the first table is the previous result. Unlike Criterium, when benchmarking JMH utilizes separate Java processes, which it calls forks. Running functions directly as code in the same process, like you would with Criterium is also supported, but it's not ideal for some important reasons. In fact, JMH goes so far as to warn you against it if you try. We can see in the interleave results that they are more or less identical to the first result. Actually, if you look at the complete JMH dataset, the results are almost like clockwork. Across the full runs, each type and size combination result is usually within one to two nanoseconds. A lot of time less. While the Criterium dataset is overall more varied. And I do want to say, some of you might be thinking right now, we're measuring nanoseconds here. Does this really matter that much? Well, first when writing code to be as fast as possible, nanoseconds actually do matter quite a bit. Nowadays on the JVMs, reading array elements in a predictable linear fashion can report sub nanosecond element access times due to vectorization performed by the jet, for example. But secondly, this is just an example. For real benchmarks that are measuring something useful, the effect can and will be more pronounced. Again, the exact number is not really the point. They'll be different on different hardware. This is about being able to measure consistently and produce stable data. Here's a pertinent quote from the JMH docs. JVMs are notoriously good at profile guided optimizations. This is bad for benchmarks because different tests can mix their profiles together and then render the uniformly bad code for every test. Forking each test can help evade this issue. And forking is just one of the many things JMH does for you to increase consistency and accuracy. I should say too that Criterium isn't doing anything quote unquote wrong here. And I'm definitely not trying to defame it. Here, it's just at the mercy of the underlying jet. A lot of times you will definitely have multiple implementations running side by side in a code base with an interface or similar. And you want your test to reflect this biomorphic or megamorphic environment. And again, JMH supports this as previously mentioned. However, when comparing implementations with the intent to choose one over the other, it can be counterproductive. And forking isolates you from this type of problem. And real quick, I will mention that these problems are maybe more broad that you might think. Here we have some similar sounding issues regarding Haskell's Criterion Library, which was an inspiration for Criterium. These are some excerpts from comments of some open issues, the first of which being several years old. We've seen the title of the first one. It is talking about benchmarks being influenced by the existence or absence of other benchmarks. And in the second, an excerpt from a comment is talking about the solution being to run tests in a separate process. I don't know about you, but this was all very interesting to me, similar sounding problems all without a jet. So now we're gonna get to the main part of the talk where I'm going to start with the most basic example and then gradually show off some more of JMH and JMH closures features. Note that this can't be a full JMH tutorial if I tried to cover all the features, this would be a much longer talk. But the Java docs are very well written and tutorial-like, so if you wanna learn more, read those, that's what I did. First, we're going to quickly set up line JMH, a simple front-end that I wrote with some convenience features. Keep in mind this library works bare bones too, it's not a requirement. Anyway, in our project file, we're gonna make sure to clear the default arguments added by line again in the JMH profile since these prevent some important compiler optimizations which give us the fastest possible code. This first example is going to show you one of the pitfalls of benchmarking in the JVM. Again, I'm not able to assume the level of familiarity with the subject. This is an interesting example nonetheless. So I wanna get this way out of the way right up front. These type of problems exist even when using JMH. We're going to attempt to measure a function that does nothing as a baseline. We were gonna try to answer the question of how much overhead JMH is imposing by comparing against some subsequent tests. Do keep in mind that these type of benchmarks are very artificial. Some of the problems we're going to see here won't come up with functions that do real work, but they're important things to be aware of nonetheless. So we have a function in our core namespace from before, that's very exciting, it's empty. Now we're a benchmark data file. We have Eden data that is specifying our empty function as our sole benchmark. And to run it, we're telling the plugin just to show us the score. You can see here only, and the keys we're interested in of the result maps. This is JMH terminology for the primary result of the benchmark. Let me get my mouse out of the way. We're only using one fork. Less forks equal quicker benchmarks with the trade-off being less confidence in the result. One will be fine for our purposes here. And JMH is going to use throughput mode by default. It measures operations per time unit, seconds if we don't explicitly tell it otherwise. In this case, operations mean function calls. Now the result. JMH informs us that we can do over 200 million nothings per second. Okay, we'll keep this in mind. So let's compare to doing a trivial operation like adding two primitives. Don't worry about where the arguments to our function are coming from for the time being. Real quick, I do want to note that JMH closure is aware of the primitive metadata and will compile the benchmark using one of closure special primitive interface types. So no boxing will occur. That would influence the results. I'm gonna show the benchmark data file later after I explain a few more things. What we're interested here in is the results. Okay, wait, it's faster than doing nothing. Nine million more measured operations per second. So this has to do with how JMH uses the return value of functions which are passed to what it imposingly calls black holes. Basically these ensure that the results and therefore the function calls themselves are not optimized away so it can accurately measure them. Here the empty function execution time is being inflated due to the increased cost of consuming its return value. It's a very small cost but even with a nil reference it still is noticeable. Most of the time this overhead will be a very tiny fraction of your benchmark but for artificial tests like these they'll be more apparent. I have ran these tests more than once and sometimes the empty function is slightly faster and sometimes like here the addition is slightly faster. Anyway, we can get back on track. We can quote unquote fix this and construct a benchmark that is always measurably faster. And there is a reason to all this so just to indulge me for a second. Instead of a function that returns a nil object reference we return a constant primitive. So simply returning a constant is faster than doing the addition. I've run this a few times and I get at least 30 million more measured operations per second. So we've learned here that JMH can consume an immediate primitive value like along slightly faster than an object reference or even a nil one. But we still have an answer to the initial question to do so we really need to do nothing. So we need to revive an idiom that most of the time has no place in closure the void method. Closure concept of a function that does nothing is one that returns an object that represents nothing. This is a different thing at the byte code level. We can tell the compiler to generate a void method like this. We see the normal way to specify a benchmark. By giving a map that gives the function along with options and other things that I'll get to later. We use the void flag here. Now we're gonna see a dramatic result in our result. We're gonna see a dramatic change rather in our result. This result is very much not real however. My machine here cannot actually achieve this many function calls per second. With nothing for JMH to consume and therefore no visible effect our function has been completely removed by the JIT. I've taken the time to go through all of this for good reason. If you ever see results like this that seem way too high most of the time the JIT has determined that your function or parts of your function do no visible work and can be optimized away. Like this function here that never uses the result of an expensive computation. In this case the JIT will likely remove the code. While it's obvious here what's going on a lot of times it will be less so. For advanced cases like this you can prevent this from happening by using black holes explicitly. Keep in mind that you will rarely if ever need to do this in practice at least for normal benchmarks. So again I'm sorry for this slight tangent here. What this is trying to show you is that you can't always trust the results you get even from JMH. Here are some relevant quotes from the docs. To gain reusable insights you need to follow up on why the numbers are the way they are. Do not assume that the numbers tell you what you want them to tell. Okay with that out of the way the rest of the talk is gonna be more straightforward which is good. We're gonna start by demonstrating in more depth the benchmarking modes provided by JMH. We're gonna add another file to our names excuse me we're gonna add another benchmark file and add another function to our namespace. Here in the data we're explicitly setting the mode and the time unit used for our result. And the function is simply sleeping for a hundred milliseconds. When we run we get around 10 operations again function calls per second as we would expect. The docs say of this mode it measures the raw throughput by continuously calling the benchmark function in a time bound iteration and counting how many times it executed the function. So what does this mean exactly? Most modes use this time bound iteration which just means that a function will be measured until the iterations period expires. We get five iterations each 10 seconds long and also five warm up iterations also 10 seconds long. So in the default configuration most modes can be expected to run for about a hundred seconds in total that's 50 seconds of warm up and 50 seconds of measurement in that order. And this is per fork mind you. The next mode is average and this one is easy to explain. It's simply the reciprocal of throughput mode. So we see here that our sleep function takes about one tenth of a second as expected. Note here to change modes we didn't actually have to change anything on our file. We can override the options given in the file which are actually just defaults by passing options to the runner. As we see right here. The final two modes are sample and single shot. We show here that you can actually specify a sequence of modes to run. So we're now gonna have two results one for each mode. Single shot measures only a single function invocation. The normal iteration time is not used in this mode. So as soon as the benchmark function returns iteration is over. I mainly use this for testing before an extended run. It can also be used to measure cold performance. So how fast the code is before the jet has a chance to optimize it. And the sample mode randomly samples the function's execution time. It will automatically adjust the sampling frequency depending on how long your function takes to execute. These last two modes especially sample are a bit more specialized in their application and using them effectively can require a bit more experience with JMH. In my experience most of the time the average modes, excuse me, the throughput of the average modes are what you're gonna want especially if you're new to JMH. And I should mention another convenience feature the plugin provides is table output. So we see here in the sample mode percentiles and some additional data displayed in an easier to read way, excuse me. You can also always enable the default JMH log via the status option which I use actually quite frequently. But there's something missing here. Most of the time your benchmarks will need input. For this we use states. We specify states similarly to benchmarks by giving a function. The difference being that a state's job is just to produce a value for a function that specs, excuse me. The state's job is just to produce a value for a function that uses it via a state keyword. To start with we have a function in our demo in our new demo state namespace that produces a vector filled with random numbers. We now add a new benchmark to our core namespace. The sum function expects an input sequence which will be provided by our state. The benchmark data now features a new key that gives the available states. And the function we're testing uses the args key to give its inputs. Here it's the VEC state that the arrow is highlighting that. Now to run. On my machine I can sum a small vector about one million times a second. Later we're gonna make states a lot more useful when we get to parameters. For example, parameters will allow us to dynamically size the vector. Also state creation functions are run before benchmarks and are not and their execution time is not gonna affect the overall measurement. This is an important property. There is a caveat to this that is a more advanced topic. You can see more about that in the docs. Okay, states have a lot of options that can get complicated for advanced use cases like heavily concurrent benchmarks. But most of the time they're pretty simple. To continue looking at states, we're gonna continue looking at states by measuring the performance of updating a closure atom that is uncontended versus heavily contended. This is the kind of thing that makes JMH really shine in my opinion. So first we have a function that swaps an ever-increasing integer to a provided atom. I'll just mention here that we could actually just put this INC0 helper inside the DEFEN. If you look at the generated bytecode, we see that closure actually hoists this out by default since all the arguments are constant. But we're gonna be explicit here by wrapping with a let. Now a new data file. There are two defined states. These are using function expression data instead of var symbols. This is a convenience feature and it's mainly intended for very simple states like this. They're best used sparingly. We're using closure's built-in atom function. The important thing to notice here is that they have different scopes. So the first one named global uses the benchmark scope. This is the default. It means that only one state will ever be created during the entire run essentially. This will make it heavily contended depending on how many benchmark threads you tell JMH to use. The other state is specified with the thread scope, meaning that each benchmark thread will have a thread local state value created specifically just for it. Meaning here that it will be completely uncontended. So for this run, we're gonna tell JMH how many worker threads to use. We're still only forking once one Java process, but the process will utilize four threads running their own iterations invoking our reset atom function. Keep in mind, JMH synchronizes threads by default, which means that each worker thread waits for each other to be ready before running an iteration. Again, by default, there are five iterations. So to recap, we had two benchmarks of the same function. That means we're gonna have two results and when each benchmark was run, our function was called for multiple threads with one atom, with an atom whose thread visibility is managed by JMH. And we can see here for this test on my machine, an uncontended atom is around an order of magnitude faster with a simple update function. Real quick, think about what JMH is doing for you here and imagine having to set up a similar benchmark harness manually. There's also a lot more JMH can do for you if you're writing concurrent benchmarks, like worker thread groups and desynchronization. Okay, I quickly wanted to explain in full the rationale behind using data to represent our benchmarks and states. Some of you may understandably perceive this as unnecessary ceremony or verbosity. Why do this? First, this is what enables the automatic state management shown before. If you're passing the state arguments to your test functions manually or capturing them in a closure, that's an S, not a J, this won't work. There are thread semantics, life cycles, and so on. Letting the framework managed state was the concept foreign to me when I first started using JMH and now I find it really helpful. Not having to create your own makeshift harness when testing a function with varying implementations and sizes of arguments like the indexing benchmark we saw earlier. And second, more importantly, this is what enables the process isolation feature. For example, how would JMH fork your benchmark code in an isolated process if you were attempting to test a function that only existed in memory, like in a REPL? Keep in mind forking in the Unix sense of the word which is not what we're talking about here where a process shares a copy on write address space with its parent process doesn't exist on all platforms. So to be able to utilize forking your benchmarks and states must be loadable from the file system via the normal closure require function. Or function expression data must be able to be evaluated in an empty compilation environment. This is why function expressions are best used sparingly. This caveat is not usually noticed in practice but it bears mentioning. JMH was meant to be used from ahead of time compile languages like Java. If you're curious about what's going on under the hood you can see the wiki for more. It's not very interesting. It's basically just jumping through a bunch of hoops to do, do note that this is all hidden from you and you don't usually need to know anything about this to use the library effectively. And yeah, the data specification may open up other possibilities as well. I've never used these things but maybe somebody could find a way to make this more interesting. Getting back to the examples. For more complex state values we can use life cycles. Let me check the time over. I'm just seeing the time here. So if you had a test that required a temporary file during the run you would write something similar to this. Instead of just giving a state function via the fun keyword, right here, excuse me, instead of just giving the state function via the fun keyword we're instead using the setup and tear down life cycle keys. In fact, the fun keyword for states is actually just an alias for the setup key. So running this benchmark will create a temporary file, one for each fork and delete it before the run concludes. There's quite a bit more to life cycles that I don't have time to get into right now. Real quick, just know that what we've been specifying previously for states is actually shortcuts. Each state can utilize a setup and tear down function at one of three levels. In the order of execution the trial level which is what we saw with the temp file, the iteration level and then finally the invocation level. Also for advanced use cases states can also use other states via their own args key. All the info on this is in the sample file that's in the JMH closure repo. If we have time at the end, I can come back and show a more complex example that uses multiple levels. That's pretty cool, but it wants to see more. One of the things that is different about JMH than some other libraries is that it explicitly discourages using loops. For a somewhat contrived example once again, our addition operation from before. Here's what the data file could look like right here. Now you might think the overhead of calling the add function would dwarf such a trivial operation and maybe we should minimize the overhead by doing the operation some amount of times in a loop instead. Here to attempt to offset the cost we're doing the addition via a loop, a closure loop, an arbitrary amount of times. This is the kind of thing I used to do when I was benchmarking in criterion. Sometimes it seemed like it helped to run, instead of running a function that I perceived to be essentially too short to measure, I would do it some amount of times in a loop. Again, this is a contrived example, but apparently sometimes this sort of thing is even encouraged by some benchmarking libraries to measure short operations, small operations like this. There are exceptions, but usually for JMH you don't want to do this. To quote the docs again, you will see there is more magic happening when we allow optimizers to merge the loop iterations. Also in many cases, the function call will be inlined away. Real quick, I'll explain this. For a tiny function like add, the call site will almost certainly be inlined by the JIT into the method that's generated by JMH closure. And this generated method is itself explicitly inlined by JMH. The moral of the story being, most of the time inlining can make your function overhead distance appear. Almost done now with the tutorial type of examples. Next, we have params. These are very useful with states. So we want to test a couple of functions that operate on an integer array. The first uses the built-in Java array hash code method and the second one uses closure's hash function, also known as hashEek. Here in our data file, we can see one of the shortcuts that JMH closure provides. The NS keyword, excuse me, the NS keyword allows us to save some typing when testing functions in the same name space. The state here, called interay, takes a parameter as its only argument. The parameter is defined right below it. So we're gonna measure the performance of arrays of differing lengths. Now the results with size 100. Why is the hash code so much slower? Well, in one second. Importantly, params like options are defaults. They can be overridden. This is what makes them useful. We can change the size of the vectors dynamically and we can also specify multiple values. As we do here, specify a size of 1000 and a size of, what is that, one million. So here we can infer based on the throughput alone that closure's hash does not actually look at array elements. This is not surprising because it exists mainly to be used with closures built-in data types. Notice we have four results, one for each combination of parameter and function. I'm not sure exactly how much time I have left. I think I probably have maybe five to 10 minutes. I'm not sure, but I'll continue. Feel free to interrupt me. Sorry, you have about 20 minutes more. Okay, I wasn't sure exactly when this started. Okay, then I'll go up it slower. Thank you. For some final examples, we're gonna look at profiling support. Let's see what JMH provides out of the box on my Linux machine. We can selectively enable one or more of these profilers by name for our run. To do this, we use the profilers option right there. We'll try the GC profiler with one of our previous tests, the sum benchmark we saw before. The secondary results related to GC are indented below the primary one when using the table format here. These are sometimes useful, but personally, I rarely use them, since JMH also supports external profilers. I prefer to use a custom one that enables Java flight recorder for the run. If you're not familiar with JFR, it's one of the most accurate profilers that I know of for the JVM. And a few years back, it was merged into OpenJDK after previously being Oracle branded JVM's only. I made a demo version that will be included in the talk repository. It's about 60 lines of AOT compiled closure. We can enable custom profilers by providing a package prefix class name. Note the, excuse me, we do need to actually have a class file on disk for these, so that's why we're compiling it first. They need to be available on the forked process class path. So here's a snapshot I took with the SUM benchmark. I wasn't gonna show this in Java Mission Control, and I can do that at the end, but I'm not sure I wanna try switching the screen right now. Java Mission Control, if you don't know, is another very useful tool now under the OpenJDK umbrella for doing profile data. And by the way, this is the easiest way that I know of to run JFR for closure code. The alternative is doing the setup manually, starting the new JVM process with the appropriate arguments and then explicitly running the code you want to profile. So it's pretty neat. Okay, now I'm gonna look at some things that I didn't have time to cover more completely, although since I have more time than I thought I did, I'm going to spend maybe a bit of extra time on them. The first one is selectors. These are for running only a subset of the benchmarks. They're similar to line-again test selectors, if you've used those. So here we have two selectors, one called non-void and one called SUM. I'll explain the SUM one here. This is function expression data again, and here it's composing three functions, and it's going to look at the map, which in this case is a normalized benchmark map. So like for example, if you just specified a symbol for your benchmark, it's gonna be normalized to have the symbol being denoted by the fun keyword. It's taking the name of the fun and then comparing then it's checking if the name is SUM. And if so, it's going to select that benchmark. And again, these are provided to the runner using the defined keyword. So we can see here, we can select this keyword and it will select all benchmarks that match the selector. I use these all the time. Next, option sets are for defining named aliases for groups of common options. You can also use the JMH default alias to give defaults for all your benchmarks, which is useful. You see our two benchmarks here. You pass one or more keywords denoting option sets or additional option maps as a sequence. So this one here, our function one is using the fast option set, which is the defined below it. And the second function here is using the stress option set along with providing new options. These are merged from left to right. And again, the defaults are merged first. So other options specified later are going to override these. This is a lot better than annotations. If you've ever used JMH, trying to avoid boilerplate is nearly impossible. You can change the JVM arguments for fork processes. Like here, we're turning on enclosures direct linking flag for faster var performance. And there are a few more things regarding function specifications.  You can also apply a function to a variable sequence of arguments using the apply flag. So like here, we would do this for that. Finally, external benchmarks and states are also supported. Compiled via gen class or by compiled from another JVM language entirely. You just have to use package prefixed symbols. For benchmarks, you just need to provide your classes to the externs runner option right here. They'll be run alongside any closure tests. This can be useful to compare JVM language performance, which I've done actually multiple times. And external states can be given in line. There are a very small amount of advanced state techniques that require this method. Since I have some extra time, I'm going to go back and show the more complex state example. So I was saying before that state life cycles are run in a specific order, an specific named order, the trial iteration, then invocation levels. So this temp file state here is running by default since we're not specifying what level we want in the trial level, which is going to be essentially run once for the entire benchmark for the entire run. And the tear down is going to be run at the end of the entire benchmark. A more complex example, for a more complex example, we see here we're going to have a kind of like a mock service. This is all empty because I'm just showing an example here. But we have a protocol for disposing a type of resource. We have a protocol, we're going to call resource, and we have a service. The service implements disposable, I dispose, excuse me, and I resource. And the resource is producing another disposable resource. Again, this is kind of unnecessary. I mean, I'm just trying to show an example. These are all empty, so. So here the benchmark itself doesn't matter. But we have one state. The trial level is going to be calling our state payload function. We're going to see that here. This is just creating a map. And we're putting whatever we want in this map. This is going to be available through the entire run. So we were adding our service from before. At the end of the entire benchmark run, we're going to be disposing the service, which we see below. This is just taking the service key out of the map and disposing it. And in this case, the return value doesn't matter because we're at the end, essentially, of the lifecycle. The invocation level is run before and after each individual benchmark. Each individual function is called. So in this case, let's imagine we need each benchmark to be provided with a transient resource that is yielded from the service each call. So again, we're using this with resource setup fixture function. And we're taking the service that we created here out. And we're adding a resource to the payload. And similarly, when the function is done running, we're disposing the resource and removing it from the aggregate payload. This is maybe slightly more complicated than I should be showing here. But it just shows you what this would look like if you had your benchmarking a web service, that type of thing. So again, OK. So now I hope you understand a bit more about JMH and how to use it from closure in hopefully an idiomatic way. Just a few final thoughts. You know about some of the benefits of JMH. What about the downsides? JMH is not simple. And there is a lot to learn. This is the main drawback. It's not simple because the JVM is not simple. There are lots of options. And to use it effectively requires more effort than you might be used to. Also, JMH is quite a bit more heavyweight than some alternatives. But it's because it's also handling a lot more for you. Benchmarking the JVM is tough in large part due to its inherent non-determinism. That's just the truth. While it's great how the concepts of closure fit together so beautifully and simply, what closure is running on these modern VMs like hotspot are complex. When you choose to benchmark in one of these advanced environments, you're suddenly exposed to a lot of very intricate stuff. I've recently done some work with OCaml, for example. And it's literally night and day how much more straightforward to understand what's going on under the hood is there. But again, there are always trade-offs to any technical decision, whether language or platform. The dynamic nature of the JVM that makes this stuff a challenge is what makes closure such a joy to use as it compiles code on the fly in a REPL as you're patching a running system. Regardless of the challenges, I think writing fast, well-optimized code is an important and attainable goal. In a similar way to how ClosureScript leverages Google Closure to handle some of its important underlying machinery, we may want to consider a widely used battle-hardened tool created by open JDK JVM experts. JMH goes to lengths greater than any other tool that I know of on the JVM to ensure accurate micro-benchmarking. However, as mentioned at the start, this is not meant to be a knock against any other library. Depending on what you're doing and the features you need, as long as you're aware of some of the pitfalls described here, you can still be effective using alternatives. Criterium in particular is a great choice and it is very well-written. I would recommend reading the source if you're interested in JVMs or statistics. It's much more digestible than the sprawling Java code base of JMH. Additionally, even if you decide to adopt JMH because you need more strenuous benchmarks or some of its advanced capabilities, it's not a panacea. As shown at the beginning with the empty function example, it's still possible to get it wrong with this library. And as always, your hardware operating system, JVM, vendor, version, configuration, and many other factors will affect your benchmarks. Your results may vary. So if you want to know more, begin. Please see the sample file provided in the repo along with the wiki there and check out the Java docs and sources of the JMH samples project. Some of my examples here were inspired or adapted from the samples there. Also, I recommend these blogs if you want to learn more about performance on the JVM, among many other good ones. So finally, I'd like to thank both the authors and contributors of both Criterium and JMH for their work. And once again, thank you to Bruno for inviting me and for organizing this event. I don't know much time I have left, but if anyone has any questions, I'd be happy to take them. Otherwise, thank you for listening.