• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Czy opłaca się poświęcić czytelność dla kilku linii kodu mniej?

VPS Starter Arubacloud
+1 głos
647 wizyt
pytanie zadane 21 września 2021 w JavaScript przez Doge Gaduła (3,420 p.)

Witam, czy lepiej jest zaoszczędzić kilka linii kodu, ale stracić lekko na czytelności czy jednak na odwrót? Przykład:

if(field == 5 || field == 15 || field == 25 || field == 35) color = 'gray';
    switch(field)
    {
        case 5:
        case 15:
        case 25:
        case 35:
            color = 'gray';
            break;
    }

 

4
komentarz 21 września 2021 przez icytower Bywalec (2,170 p.)
czytelnosc zawsze na propsie.

3 odpowiedzi

+3 głosów
odpowiedź 22 września 2021 przez Milesq Nałogowiec (32,020 p.)

Generalnie tak, ale tu też nie zrobiłeś tego najlepiej. Może lepiej tak?

const grayFieldIds = [5, 15, 25, 35]

if (grayFieldIds.includes(field)) {
    color = 'gray'
}

 

1
komentarz 22 września 2021 przez Ehlert Ekspert (213,530 p.)
IMO warto opakować w metodę z odpowiednią nazwą z zwracać boolean.
1
komentarz 22 września 2021 przez Wiciorny Ekspert (275,550 p.)

@Milesq, Imo optymalizacja ... jest ważniejsza :).
Kod jest wazny i powinien być czysty, ale to co napisałeś w rzeczywistosci robi cos takiego 

 

$({ target: 'Array', proto: true }, {
  includes: function includes(el /* , fromIndex = 0 */) {
    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
  }
});

w takim razie, wyobraź sobie :D że u Ciebie dla każdego warunku  i elementu wykonujesz taką kobyłę :)
Problem dla 4 elementów ? Żaden :). problem dla setek tysięcy elementów przy wielu żądaniach ? 
Ogromny.

komentarz 22 września 2021 przez Doge Gaduła (3,420 p.)

Trochę źle w temacie podałem, ponieważ powinienem wkleić całego switcha, który wygląda tak:

    switch(field)
    {
        case 5:
        case 15:
        case 25:
        case 35:
            color = 'gray';
            break;
        case 1:
        case 3:
            color = 'hsl(19, 47%, 40%)';
            break;
        case 6:
        case 8:
        case 9:
            color = 'hsl(200, 89%, 82%)';
            break;
        case 11:
        case 13:
        case 14:
            color = 'hsl(325, 68%, 54%)';
            break;
        case 16:
        case 18:
        case 19:
            color = 'hsl(33, 93%, 54%)';
            break;
        case 21:
        case 23:
        case 24:
            color = 'hsl(357, 85%, 52%)';
            break;
        case 26:
        case 27:
        case 29:
            color = 'hsl(57, 100%, 50%)';
            break;
        case 31:
        case 32:
        case 34:
            color = 'hsl(144, 70%, 41%)';
            break;
        case 37:
        case 39:
            color = 'hsl(203, 100%, 37%)';
            break;
    }

i wtedy odpowiednik z else if wyglądałby tak:

if(field == 5 || field == 15 || field == 25 || field ==35) color = 'gray';
    else if (field == 1 || field == 3) color = 'hsl(19, 47%, 40%)';
    else if (field == 6 || field == 8 || field == 9) color = 'hsl(200, 89%, 82%)';
    else if (field == 11 || field == 13 || field == 14) color = 'hsl(325, 68%, 54%)';
    else if (field == 16 || field == 18 || field == 19) color = 'hsl(33, 93%, 54%)';
    else if (field == 21 || field == 23 || field == 24) color = 'hsl(357, 85%, 52%)';
    else if (field == 26 || field == 27 || field == 29) color = 'hsl(57, 100%, 50%)';
    else if (field == 31 || field == 32 || field == 34) color = 'hsl(144, 70%, 41%)';
    else if (field == 37 || field == 39) color = 'hsl(203, 100%, 37%)';

 

komentarz 22 września 2021 przez Ehlert Ekspert (213,530 p.)

@Wiciorny, tak działa js.

komentarz 22 września 2021 przez Wiciorny Ekspert (275,550 p.)
nie, tak działa brak myślenia w przypadku "chęci"  zwiększenia czytelności nad funkcjonalnością.
To samo się tyczy często kiedy chcemy coś na siłe optymalizować :) a wychodzi gorzej, albo chcemy napisać przekodowanie na bazie, sql jakieś kombinując z zapytaniami, gdzie się okazuje że staje się to bardzo nieoptymalne "ale ładniej clean code wygląda"
3
komentarz 22 września 2021 przez Milesq Nałogowiec (32,020 p.)

@Wiciorny, 

Problem dla 4 elementów ? Żaden :). problem dla setek tysięcy elementów przy wielu żądaniach ? 

 Imo optymalizacja ... jest ważniejsza :).
Kod jest wazny i powinien być czysty

Trochę zależy w jakiej branży. W embeded faktycznie może być tak, że czasem chodzi o każdy byte i każdą nanosekundę, ale spotkałem się ze stwierdzeniem, że DX (developer experience) jest zazwyczaj ważniejszy od takiego szukania mikro-ulepszeń wydajności. Czas programisty jest droższy niż te maks kilka sekund które można zaoszczędzić i lepiej, żeby cały kod był pisany w sposób jak najczystystszy, bardzo pomoże to nowym devom w projekcie. Tym bardziej, ze jak sam zauważyłeś, o ile jedno użycie takiego patternu nie sprawi, że developer się pogubi, to jeśli będziemy tego używać na każdym kroku, to może być mu o wiele ciężej czytać ten kod.

Druga sprawa, to czy na pewno if/else jest w tym wypadku wydajniejsze? Zrobiłem szybki eksperyment i uruchomiłem ten kod, nie kilka tysięcy razy (jak zasugerowałeś) ale 10 miliardów razy.

Wyniki były za każdym razem podobne. If/else jest najmniej wydajne, a pozostałe 2 rozwiązania praktycznie tak samo.

 

ifElseHell: 10.970s
switchCaseLimbo: 7.482s
includesHeaven: 7.434s

ifElseHell: 10.289s
switchCaseLimbo: 7.324s
includesHeaven: 7.374s

ifElseHell: 9.784s
switchCaseLimbo: 7.696s
includesHeaven: 7.243s

 

function ifElseHell(field) {
    if(field == 5 || field == 15 || field == 25 || field == 35) return true

    return false
}

function switchCaseLimbo(field) {
    switch(field)
    {
        case 5:
        case 15:
        case 25:
        case 35:
            return true
    }

    return false
}

function includesHeaven(field) {
    const grayFieldIds = [5, 15, 25, 35]

    return grayFieldIds.includes(field)
}

const MAX = 10_000_000_000

console.time('ifElseHell')
for(let i=0;i<MAX;++i) {
    ifElseHell()
}
console.timeEnd('ifElseHell')

console.time('switchCaseLimbo')
for(let i=0;i<MAX;++i) {
    switchCaseLimbo()
}
console.timeEnd('switchCaseLimbo')

console.time('includesHeaven')
for(let i=0;i<MAX;++i) {
    includesHeaven()
}
console.timeEnd('includesHeaven')

Tak więc w tych konkretnych przypadkach moje rozwiązanie jest o ironio najbardziej wydajne (języki programowania potrafią potrafią się optymalizować, a zwłaszcza metody takie jak .includes, które są pisane nie w js'ie tylko niżej).

Nie twierdzę, że zawsze jest to najszybsze rozwiązanie, ale uważam, że zmiana kodu, żeby uzyskać program 14ms szybszy na 10MLD iteracji, nie jest dobrym pomysłem 

4
komentarz 22 września 2021 przez tkz Nałogowiec (42,020 p.)

Trochę zależy w jakiej branży. W embeded faktycznie może być tak, że czasem chodzi o każdy byte i każdą nanosekundę, ale spotkałem się ze stwierdzeniem, że DX (developer experience) jest zazwyczaj ważniejszy od takiego szukania mikro-ulepszeń wydajności.

W embedded również, nie optymalizuje się czegoś jeżeli nie ma takiej potrzeby. Abstrahując, że optymalizacja dla samej optymalizacji to przepalanie środków. 

4
komentarz 24 września 2021 przez Comandeer Guru (604,400 p.)

@Wiciorny, za każdym razem, gdy ktoś myśli, że ręcznie zoptymalizuje kod lepiej niż JiT JS-a, odsyłam go do https://mrale.ph/blog/2014/12/24/array-length-caching.html

Większość optymalizacji, jakie się robi ręcznie, jest całkowicie nieistotna. O wiele większym problemem w JS-ie jest jego jednowątkowość i fakt, ze jest odpalany razem z renderowaniem strony. Tutaj jest więcej problemów niż z optymalizacją przeszukiwania tablicy – które zaczyna mieć problemy przy tablicach o wielkości wystarczająco dużej, by większość programów nigdy się na nie natknęła.

1
komentarz 24 września 2021 przez Wiciorny Ekspert (275,550 p.)
Ja to bardziej mówiłem ogólnie, wiesz... nie jestem javascriptowcem, ale coś takiego np w javie no nie zawsze, nie zawsze podkreślam jest dobrym rozwiązaniem.
Ale dzięki poczytam super
+1 głos
odpowiedź 24 września 2021 przez VBService Ekspert (255,440 p.)
edycja 24 września 2021 przez VBService

Może zrób to w formie tablicy.

 

Przykład

<div class="field"></div>
<button>Losuj kolor</button>
* {
  margin: 0.2em;
}
.field {
  width: 5em;
  height: 5em;
  text-align: center;
  line-height: 5em;
  transition: background-color 1s;
  color: white;
}
const field_color = [
  { 'color':'gray',                'field': [ 5,15,25,35 ] },
  { 'color':'hsl(19, 47%, 40%)',   'field': [ 1,3,21 ] },
  { 'color':'hsl(200, 89%, 82%)',  'field': [ 6,8,9 ] },
  { 'color':'hsl(325, 68%, 54%)',  'field': [ 11,13,14 ] },
  { 'color':'hsl(357, 85%, 52%)',  'field': [ 2,4,7 ] },
  { 'color':'hsl(57, 100%, 50%)',  'field': [ 10,12,16,17 ] },
  { 'color':'hsl(144, 70%, 41%)',  'field': [ 18,19,20,22 ] },
  { 'color':'hsl(203, 100%, 37%)', 'field': [ 23,30,31,34 ] },
  { 'color':'black',               'field': [ 24,26,27,28,29,32 ] }
];
const MAX_FIELD_NUMBER = 35;
const div_field = document.querySelector('.field'),
      button    = document.querySelector('button');

button.addEventListener('click', setFieldColor);
setFieldColor();

function setFieldColor() {
  const field = parseInt(Math.random() * (MAX_FIELD_NUMBER - 1) + 1);
  div_field.textContent = field;

  for (const row of field_color) {
    if (row.field.includes(field)) {
      div_field.style.backgroundColor = row.color;
      break;
    }
  }
}

 

komentarz 24 września 2021 przez Milesq Nałogowiec (32,020 p.)
Fajny przykład, ale jedna funkcja nie powinna zarówno wyznaczać koloru jak i go ustawiać bezpośrednio na elemencie DOM. Jedna funkcja powinna po prostu pasujący kolor zwracać
0 głosów
odpowiedź 24 września 2021 przez Aisekai Nałogowiec (42,190 p.)

Jeżeli możesz sobie pozwolić na poprawę czytelności nieznacznym (o ile taki będzie) spadkiem wydajności - nie widzę przeszkód. 

 

 

 

Z tym że, tutaj możesz to zrobić zarówno lepiej i wydajniej: zrób sobie obiekt z numberami jako propertyName i czymkolwiek co będzie truthy jako wartość. 

const colors = {
 5: 'grey',
 10: 'grey',
...
}

A potem po prostu robisz `colors[field` - i albo wyciągasz kolor przypisany, albo sprawdzasz czy jest truthy i zwracasz np. szary.

 

Podobne pytania

0 głosów
1 odpowiedź 919 wizyt
pytanie zadane 21 lutego 2018 w JavaScript przez mi-20 Stary wyjadacz (13,190 p.)
0 głosów
1 odpowiedź 365 wizyt
pytanie zadane 25 maja 2017 w PHP przez Ziuziek Mądrala (5,140 p.)

92,833 zapytań

141,777 odpowiedzi

320,824 komentarzy

62,164 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...