“there is nothing like a tested, integrated system for bringing a forceful dose of reality into any project. Documents can hide all sorts of flaws. Untested code can hide plenty of flaws. But when people actually sit in front of a system and work with it, then flaws become truly apparent: both in terms of bugs and in terms of misunderstood requirements.”
Recent Updates Toggle Comment Threads | Keyboard Shortcuts
The way we have traditionally measured performance and optimized our games encouraged a lot of conditional operations – recognizing that a particular operation doesn’t need to be done in some subset of the operating states, and skipping it. This gives better demo timing numbers, but a huge amount of bugs are generated because skipping the expensive operation also usually skips some other state updating that turns out to be needed elsewhere.
We definitely still have tasks that are performance intensive enough to need optimization, but the style gets applied as a matter of course in many cases where a performance benefit is negligible, but we still eat the bugs. Now that we are firmly decided on a 60hz game, worst case performance is more important than average case performance, so highly variable performance should be looked down on even more.
It is very easy for frames of operational latency to creep in when operations are done deeply nested in various subsystems, and things evolve over time. This can lay hidden as a barely perceptible drop in input quality, or it can be blatantly obvious as a model trailing an attachment point during movement. If everything is just run out in a 2000 line function, it is obvious which part happens first, and you can be quite sure that the later section will get executed before the frame is rendered.
Besides awareness of the actual code being executed, inlining functions also has the benefit of not making it possible to call the function from other places. That sounds ridiculous, but there is a point to it. As a codebase grows over years of use, there will be lots of opportunities to take a shortcut and just call a function that does only the work you think needs to be done. There might be a FullUpdate() function that calls PartialUpdateA(), and PartialUpdateB(), but in some particular case you may realize (or think) that you only need to do PartialUpdateB(), and you are being efficient by avoiding the other work. Lots and lots of bugs stem from this. Most bugs are a result of the execution state not being exactly what you think it is.
In almost all cases, code duplication is a greater evil than whatever second order problems arise from functions being called in different circumstances, so I would rarely advocate duplicating code to avoid a function, but in a lot of cases you can still avoid the function by flagging an operation to be performed at the properly controlled time.
To sum up:
If a function is only called from a single place, consider inlining it.
If a function is called from multiple places, see if it is possible to arrange for the work to be done in a single place, perhaps with flags, and inline that.
If there are multiple versions of a function, consider making a single function with more, possibly defaulted, parameters.
If the work is close to purely functional, with few references to global state, try to make it completely functional.
Try to use const on both parameters and functions when the function really must be used in multiple places.
Minimize control flow complexity and “area under ifs”, favoring consistent execution paths and times over “optimally” avoiding unnecessary work.
“Software design is an exercise in the management of complexity”
“Something simple that’s been “shipped” and gathering feedback, often beats what hasn’t—an idea known by the phrase and post “Worse is Better”, by Richard Gabriel .”
“Focus is about saying no. And the result of that focus is going to be some really great products, where the total is much greater than the sum of the parts.” — Steve Jobs
“Because successful programming depends on minimizing complexity, a skilled programmer will build in as much flexibility as needed to meet the software’s requirements but will not add flexibility—and related complexity—beyond what’s required.” — Steve McConnell, Code Complete, Ch. 10
“in larger projects there will often be functionality incorporated which will never be used (to little or no benefit), and as such serves only to create costs in complexity and additional cognitive load”
“Always implement things when you actually need them, never when you just foresee that you need them.
Even if you’re totally, totally, totally sure that you’ll need a feature later on, don’t implement it now. Usually, it’ll turn out either: a) you don’t need it after all, or b) what you actually need is quite different from what you foresaw needing earlier.” — Cunningham & Cunningham (C2 wiki)
“Bad programmers worry about the code. Good programmers worry about data structures and their relationships.” — Linus Torvalds
“[Design] Patterns, like all forms of complexity, should be avoided until they are absolutely necessary.” — Jeff Atwood, co-founder StackExchange
“Fewer moving parts is generally preferable…” — Twirrim on HN
“As with many other examples over the history of the Internet, it was the technology which was easiest for a beginner to pick up which won, rather than those which were most powerful for an expert.”
Whenever a discussion starts that involves PHP, on Twitter, Hackernews or Reddit or real life, it usually quickly devolves in a barrage of criticism.
A big part of this issue is that the barrier to entry in PHP is so … low, almost everyone can start hacking wordpress templates. For many people, PHP is the first programming language they try without formal education.
We’ll tell you that over 50% of the web is built in PHP, Facebook uses it sucessfully and has even gone as far as making a new, faster PHP implementation. We might tell you we’re paying our bills with PHP, we’re successful with PHP, love the commmunity, love the new wave of PHP, fueled by composer and those things would all be correct.
I’m a “getting the job done” kind of person and I live by the ideas of “Worse is Better”, so PHP is a great fit for that. I would recommend many new people who have a new business idea to start prototyping with PHP, because it’s simple and pretty easy (and cheap!) to find developers for.
The problem I have with PHP has nothing to do with the language, it’s its reputation. I can’t count the times I’ve started a conversation with a programmer who upon finding out I primarily do PHP got awkward with me.
We’re not taken as seriously, and we’re being paid less. The 2016 StackOverflow Survey puts PHP developers as the least paid. Hilariously that position is shared with “LAMP” and “Wordpress”, both of which are also PHP. We’re also among the “most dreaded”.
And to anyone considering programming as a career, or trying to get into it… stay away from PHP. There’s lots of fun, interesting languages out there that also get the job done quick, but with a better reputation and this will have an actual effect on your future career options.
90% of the work startup founders do is a complete waste.
It’s hard to know what 90% is the waste and what 10% actually matters…
- Build less features.
- Write less code.
- Do less work.
So much of time in business is wasted.
So much of the code that a company writes is wasted.
If you have a lot of people you’ll waste time doing [stuff] that doesn’t move the needle.
If you have a small number of people you’ll really be focused on saying what is the one critical thing we absolutely have to do.
The Toyota Production System historically has had four basic aims that are consistent with these
values and objectives: The four goals are as follows:
1. Provide world class quality and service to the customer.
2. Develop each employee’s potential, based on mutual respect, trust and
3. Reduce cost through the elimination of waste and maximize profit
4. Develop flexible production standards based on market demand.
By reducing inventory you expose the real problems in a production process quickly
and focus need for improvement. This notion of surfacing problems and abnormalities is a
critical concept in TPS.
it is better to stop a machine at the first sign of trouble than to keep on producing the problem which only
generates more waste.
When machines possess the ability to stop in the event of a problem then there is no need for humans to stand and watch a machines. Jidoka frees people being tied to machines and monitoring them and puts people to use in a more value added fashion.
Level Production. By smoothing or leveling customer requirements
over time, we can better utilize our resources and ensure continuous production. Averaging
volumes and model mix requires smaller lots and in the best cases “batch of one” capability from
raw materials to finished goods.
Equipment Reliability. Without reliable equipment, we must
build inventories (just in case), or invest in more equipment (due to unexpected downtime).
Proper maintenance of equipment will ensure that it is available when we need it
Respect for People
- employees as individuals and as members of their work teams.
- company goals can be reached in the best way through participation of all employees.
• setting and maintaining work standards (standards)
• solving daily performance problems (problem solving)
• participating in the continuous improvement process (improvement)
• organizing teamwork efficiently (teamwork)
Continuous improvement efforts are not limited to the production floor. All
Toyota employees and teams search for ways to continuously improve their product, process or
Quality. Taking shortcuts, doing shoddy work, or in the extreme case, putting a faulty product on a vehicle in the market amounts to an antisocial act, and can have devastating consequences for our company.
Cost. customers are demanding yearly price reductions. In order to maintain margins and profits we must continuously eliminate waste and reduce costs.
Productivity. You must consider how the necessary items can be manufactured with
the fewest labor-hours possible in the best time.
True efficiency is achieved by producing a salable quantity with the shortest labor-hours
Morale – All Toyota employees are expected to contribute to a creative, positive workplace.
Leadership must make every attempt to utilize the knowledge, experience and
creativity of all employees. This shows respect for the individuals’ dignity and worth. Creating
an environment of mutual respect, trust, and cooperation is critical for making improvements and
When quality defects are detected in the process, we must determine the root
cause, not the symptom, and implement counter measures to eliminate the defect.
“build the quality into the process.” This principle gives team members the responsibility to check quality thoroughly at every stage of their work so that defects are not passed down stream.
Consistency in methods is critical to limiting variation in the process and achieving efficient production in a timely manner.
Leveled production – smaller incremental production requirements results in more frequent changeovers, smaller batches and smaller WIP (work-in-process) inventories.
1. The money invested in materials and inventory is dramatically decreased.
2. The warehouse space needed to store the extra materials and parts is eliminated.
3. The ability to respond to manufacturing problems is improved.
4. The potential for producing large quantities of defective parts is decreased.
5. The level requirements place no excessive burden on employees or equipment.
Maintenance is important for preventing machine and equipment breakdown and for preventing
their recurrence. … Maintenance and repair are not
When purchasing new equipment, we must consider buying the minimum
capable of meeting our requirements. Reliability and ease of maintenance should be considered
before features. Bells and whistles can often be added later if the need arises. We want to avoid
buying features “just in case.” We must consider up-time, utilization and quality factors when
making equipment choices.
by Kent Beck, “the creator of Extreme Programming”.
The journeyman learns to solve bigger problems by solving more problems at once. The master learns to solve even bigger problems than that by solving fewer problems at once. Part of the wisdom is subdividing so that integrating the separate solutions will be a smaller problem than just solving them together.
Slicing. Take a big project, cut it into thin slices, and rearrange the slices to suit your context. I can always slice projects finer and I can always find new permutations of the slices that meet different needs.
One thing at a time.
Make it run, make it right, make it fast.
Easy changes. When faced with a hard change, first make it easy (warning, this may be hard), then make the easy change. (e.g. slicing, one thing at a time, concentration, isolation).
Remove extraneous detail. When reporting a bug, find the shortest repro steps. When isolating a bug, find the shortest test case.
Tradeoffs. All decisions are subject to tradeoffs. It’s more important to know what the decision depends on than it is to know which answer to pick today (or which answer you picked yesterday).
Feed Ideas. Ideas are like frightened little birds. If you scare them away they will stop coming around. When you have an idea, feed it a little. Invalidate it as quickly as you can, but from data not from a lack of self-esteem.
80/15/5. Spend 80% of your time on low-risk/reasonable-payoff work. Spend 15% of your time on related high-risk/high-payoff work. Spend 5% of your time on things that tickle you, regardless of payoff. Teach the next generation to do your 80% job. By the time someone is ready to take over, one of your 15% experiments (or, less frequently, one of your 5% experiments) will have paid off and will become your new 80%. Repeat.
The flow in this outline seems to be from reducing risks by managing time and increasing learning to mindfully taking risks by using your whole brain and quickly triaging ideas.
Be Wary of High Performers – Odds are far better than good that your high performers are achieving what appears to be high levels of productivity by building technical debt into the application by taking shortcuts whether intentionally or unintentionally.
Encourage Continual Product Improvement – Improve the database schema even if it hurts in the short term. Delete old and unused code…..continual improvement gives them autonomy and a strong sense of making valuable contributions on their own terms. Don’t underestimate the morale boost.
Encourage Code Ownership. – Management likes to reduce risk by treating developers as interchangeable… all developers being expected to be familiar with all areas of the code. That minimizes the pain when any individual developer leaves the team or the company. This is false economy. Your employees like working for you — right? — which means turnover should be low. …giving developers primary ownership of portions of the code base and not allowing other developers to change that code without approval from the primary owner. This results in higher productivity since any given developer is more likely to be familiar with the code in which they will typically be working.
Recognize Leaders – Getting back into the zone takes time. Expect your leaders to take more time to complete their projects — after all, they’re doing two jobs.
Watch Out for Misleading Metrics – Software developers aren’t stupid and some of them will quickly learn how to game the system if counterproductive incentives are visible.
Limit Interruptions – Encourage your team to prefer communication in roughly the following order so that interruptions are minimized: e-mail, chat room (if your team isn’t using a chat room yet, they should be), instant message, phone call/dropping by in person.
Prefer Private Workspaces – Audible and visual distractions should be minimized which means at a minimum each developer should have a cubicle with high cube walls and a small entrance
Encourage Experimentation – Software developers are not devoid of good ideas and have the in-the-trenches experience to have good instincts about how applications may be improved and extended.
Let Employees Leave – Forcing employees to remain in your group can never lead anywhere good. It’ll impact their morale which impacts the morale of the entire group. It’s also likely they’ll become less effective and in extreme circumstances simply leave the company.
Never Turn Down Small Requests – Unless they have a constant stream of requests that never seems to end you should never say no with only one exception: if you believe the entire team will then want the same small request and it really will impact the budget too much. … When compared to their salary and benefits these little requests go a long way toward keeping morale and thus productivity high and they cost peanuts.
Abolish Yearly and Bi-Yearly Performance Reviews – Your employees should never wait six to twelve months to discover what you feel they’ve excelled at and what they need to work on. Communication between managers and employees should be like a river that never stops flowing.
You’re Not Better than Your Employees – Just because your employees report to you doesn’t imply you’re somehow smarter or better.
Don’t Discount Younger or Older Developers
Don’t have Stupid Dress Codes
Desirable developer skills:
1 Ability to ignore new tools and technologies
2 Taste for simplicity
3 Good code deletion skills