I try to be very pedantic about having the most terse, yet readable code possible in my application. This probably means that if, for now, I only need to know how to add two vectors, I will only include a function that adds two vectors and no more. I do realize there's hidden structure there waiting to be exposed, but programming is largely about elaborating the useful structures. If the author's examples had been in…
2 is a code smell
21–30 of 33 posts
Re: 2 is a code smell
#22 1 1 1 + 2 2 2
3 3 3
(1 1 1; 2 2 2; 3 3 3) + (4 4 4; 5 5 5; 6 6 6)
(5 5 5
7 7 7
9 9 9)Re: 2 is a code smell
#23Since we've already descended into anecdotal territory, lemme drop an anecdote. I had a dot-product function which turned out to be a hotspot in some numerical code. The original function looked something like: def dot(v1, v2): return sum(i * j for i, j in zip(v1, v2)) Very functional, very pretty, very straightforward. But it was slow, both in CPython and PyPy. A bit of bytecode analysis and profiling later, we real…
Any reason you didn't just use NumPy? http://docs.scipy.org/doc/numpy/reference/generated/numpy.do...
Re: 2 is a code smell
#24Since we've already descended into anecdotal territory, lemme drop an anecdote. I had a dot-product function which turned out to be a hotspot in some numerical code. The original function looked something like: def dot(v1, v2): return sum(i * j for i, j in zip(v1, v2)) Very functional, very pretty, very straightforward. But it was slow, both in CPython and PyPy. A bit of bytecode analysis and profiling later, we real…
If you spend any time in the Clojure community, I think you'll come to an appreciation that practicality and performance are key principles of its design. The goal is to obtain both high levels of abstraction and performance.
If you're writing code where dot products are not something you do a lot of, then keeping a clean, idiomatic functional implementation is probably fine.
If you're writing code where dot products happen a lot, such as on real-time three-dimensional games (which happens to by my oeuvre), then the performance increase of having specific, unrolled implementations is huge.
Re: 2 is a code smell
#25Earlier quoted context omitted.
If you spend any time in the Clojure community, I think you'll come to an appreciation that practicality and performance are key principles of its design. The goal is to obtain both high levels of abstraction and performance.
But performance means different things to different people. If you're writing code where dot products are not something you do a lot of, then keeping a clean, idiomatic functional implementation is probably fine. If you're writing code where dot products happen a lot , such as on real-time three-dimensional games (which happens to by my oeuvre), then the performance increase of having specific, unrolled implementatio…
Re: 2 is a code smell
#26If a co-worker told me that my function was "code smell" because it took 2 arguments, I would tell him that he needs more important things to worry about.
If a coworker told me the same thing, I'd ask, "Why?" If they gave me the explanation given in the article, I'd say, "Thank you, that's a nice little improvement. The code is simpler AND more general." Then, I'd go on working, a little bit better of a programmer for it. If I repeated this ritual a few hundred times, I might actually become a halfway-decent programmer. In this field, details matter.
Knowing that difference and applying judgement is a major differentiator between inexperienced programmers and experienced ones. That, I think, is what heyrhett was getting at.
Re: 2 is a code smell
#27Earlier quoted context omitted.
If a coworker told me the same thing, I'd ask, "Why?" If they gave me the explanation given in the article, I'd say, "Thank you, that's a nice little improvement. The code is simpler AND more general." Then, I'd go on working, a little bit better of a programmer for it. If I repeated this ritual a few hundred times, I might actually become a halfway-decent programmer. In this field, details matter.
There's a difference between seeing that something can be generalized, optimized, or improved and spending the time to do it. Knowing that difference and applying judgement is a major differentiator between inexperienced programmers and experienced ones. That, I think, is what heyrhett was getting at.
Two minutes to make a minor simplification and learn a generally good way of approaching things with the tool at hand (clojure)? Count me in.
Re: 2 is a code smell
#28Earlier quoted context omitted.
But performance means different things to different people. If you're writing code where dot products are not something you do a lot of, then keeping a clean, idiomatic functional implementation is probably fine. If you're writing code where dot products happen a lot , such as on real-time three-dimensional games (which happens to by my oeuvre), then the performance increase of having specific, unrolled implementatio…
It depends on what the language and compiler do for you, the elegant form may actually be faster than your supposed uglier-but-faster optimization. As always, time-test before and (if you've decided it's necessary) after optimizing. I remember reading a warning somewhere in the Clojure docs about how using (get x idx) is much faster than (nth x idx), I don't remember why though.
Re: 2 is a code smell
#29K handles the general case: 1 1 1 + 2 2 2 3 3 3 (1 1 1; 2 2 2; 3 3 3) + (4 4 4; 5 5 5; 6 6 6) (5 5 5 7 7 7 9 9 9)
> c(1, 1, 1) + c(2, 2, 2)
[1] 3 3 3
> matrix(c(1, 1, 1, 2, 2, 2, 3, 3, 3),
+ ncol = 3, byrow = TRUE) +
+ matrix(c(4, 4, 4, 5, 5, 5, 6, 6, 6),
+ ncol = 3, byrow = TRUE)
[,1] [,2] [,3]
[1,] 5 5 5
[2,] 7 7 7
[3,] 9 9 9
Not quite so concise and elegant but it's pretty straightforward stuff for most R users.Re: 2 is a code smell
#30Earlier quoted context omitted.
If you spend any time in the Clojure community, I think you'll come to an appreciation that practicality and performance are key principles of its design. The goal is to obtain both high levels of abstraction and performance.
But performance means different things to different people. If you're writing code where dot products are not something you do a lot of, then keeping a clean, idiomatic functional implementation is probably fine. If you're writing code where dot products happen a lot , such as on real-time three-dimensional games (which happens to by my oeuvre), then the performance increase of having specific, unrolled implementatio…