• 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
591 wizyt
pytanie zadane 21 września 2021 w JavaScript przez Doge Gaduła (3,320 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,110 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 (212,630 p.)
IMO warto opakować w metodę z odpowiednią nazwą z zwracać boolean.
1
komentarz 22 września 2021 przez Wiciorny Ekspert (269,120 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,320 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 (212,630 p.)

@Wiciorny, tak działa js.

komentarz 22 września 2021 przez Wiciorny Ekspert (269,120 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,000 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 (599,730 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 (269,120 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 (251,210 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ź 816 wizyt
pytanie zadane 21 lutego 2018 w JavaScript przez mi-20 Stary wyjadacz (13,190 p.)
0 głosów
1 odpowiedź 299 wizyt
pytanie zadane 25 maja 2017 w PHP przez Ziuziek Mądrala (5,140 p.)

92,452 zapytań

141,262 odpowiedzi

319,077 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

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!

...